如何在JavaFX 2.0中创建和显示常见对话框(错误,警告,确认)?


Answers:


95

最近发布的JDK 1.8.0_40添加了对JavaFX对话框,警报等的支持。例如,要显示一个确认对话框,可以使用Alert类:

Alert alert = new Alert(AlertType.CONFIRMATION, "Delete " + selection + " ?", ButtonType.YES, ButtonType.NO, ButtonType.CANCEL);
alert.showAndWait();

if (alert.getResult() == ButtonType.YES) {
    //do stuff
}

以下是此版本中添加的类的列表:


发现这是一个很好的解决方案,我没有找到对话顶部的标题,但没什么大不了的。但是话又说回来,您是否也需要...?干杯
吉迪恩·沙宣

@GideonSassoon警报对象可以在创建后进行修改。在showAndWait()之前调用alert.setTitle()应该很好。
阿里·谢伊托

不包含外部库的Excelente解决方案
JorgeGarza

@GideonSassoon您可以设置标题文本用alert.setHeaderText("header text");,如果这是你所需要的
nonybrighto

简单等原则!谢谢^^
Mangue Sutcliff

51

编辑:对话框支持已添加到JavaFX,请参阅https://stackoverflow.com/a/28887273/1054140


2011年没有通用的对话框支持。您必须自己编写以下代码new Stage()

Stage dialogStage = new Stage();
dialogStage.initModality(Modality.WINDOW_MODAL);

VBox vbox = new VBox(new Text("Hi"), new Button("Ok."));
vbox.setAlignment(Pos.CENTER);
vbox.setPadding(new Insets(15));

dialogStage.setScene(new Scene(vbox));
dialogStage.show();

11
嗯,也许是,它们稍后会像FileChooser一样出现吗?还是他们希望每个开发人员都重新发明轮子?)
Anton

9
JavaFX 2.0的就绪标准对话框项目。为我工作
Anton


1
@Anton可以显示一个如何使用对话框的示例吗?谢谢!
likejudo 2013年

3
现在不推荐使用VBoxBuilder。尽管可以进行少量更新,但这仍然是一个有用的答案。
亚当·詹森

40

更新资料

作为RT-12643实现的一部分,JavaFX的正式标准对话框即将发布到8u40版中。它们应在2015年3月左右以最终发行版的形式提供,现在在JavaFX开发存储库中以源代码的形式提供。

同时,您可以使用下面的ControlsFX解决方案...


ControlsFX是事实上的标准第三方库,用于JavaFX中的常见对话框支持(错误,警告,确认等)。

如其他答案中所指出的,还有许多其他的第三方库可提供常见的对话框支持,并且您可以使用Sergey的答案中的示例代码轻松地创建自己的对话框。

但是,我相信ControlsFX可以轻松提供当前可用的质量最好的标准JavaFX对话框。这是ControlsFX文档中的一些示例。

标准对话框

命令链接


1
已投票,但文档链接在所链接的站点上不明显。另外网站说maven 8.0.2已启动,但对我来说仅适用于maven 8.0.1 ..并且在调用Dialogs.create()。message(“ great”)。showConfirm时得到“ Unsupported major.minor version 52.0” ();
Daniel Gerson

2
文档链接对我来说很好用。该文档当前指出“重要提示:ControlsFX仅可在JavaFX 8.0 b102或更高版本上使用。” 您可能试图针对不兼容的Java版本运行ControlsFX。如果您还有其他问题,则应将它们记录在ControlsFX问题跟踪器中
jewelsea

祝您找到该库的文档好运。
Ojonugwa Jude Ochalifu

12

Sergey是正确的,但如果需要从调用它的同一个代码块中获得自定义对话框的响应以进行评估,则应使用.showAndWait()而不是.show()。这是我对Swing的OptionPane中提供的几种对话框类型的解释:

public class FXOptionPane {

public enum Response { NO, YES, CANCEL };

private static Response buttonSelected = Response.CANCEL;

private static ImageView icon = new ImageView();

static class Dialog extends Stage {
    public Dialog( String title, Stage owner, Scene scene, String iconFile ) {
        setTitle( title );
        initStyle( StageStyle.UTILITY );
        initModality( Modality.APPLICATION_MODAL );
        initOwner( owner );
        setResizable( false );
        setScene( scene );
        icon.setImage( new Image( getClass().getResourceAsStream( iconFile ) ) );
    }
    public void showDialog() {
        sizeToScene();
        centerOnScreen();
        showAndWait();
    }
}

static class Message extends Text {
    public Message( String msg ) {
        super( msg );
        setWrappingWidth( 250 );
    }
}

public static Response showConfirmDialog( Stage owner, String message, String title ) {
    VBox vb = new VBox();
    Scene scene = new Scene( vb );
    final Dialog dial = new Dialog( title, owner, scene, "res/Confirm.png" );
    vb.setPadding( new Inset(10,10,10,10) );
    vb.setSpacing( 10 );
    Button yesButton = new Button( "Yes" );
    yesButton.setOnAction( new EventHandler<ActionEvent>() {
        @Override public void handle( ActionEvent e ) {
            dial.close();
            buttonSelected = Response.YES;
        }
    } );
    Button noButton = new Button( "No" );
    noButton.setOnAction( new EventHandler<ActionEvent>() {
        @Override public void handle( ActionEvent e ) {
            dial.close();
            buttonSelected = Response.NO;
        }
    } );
    BorderPane bp = new BorderPane();
    HBox buttons = new HBox();
    buttons.setAlignment( Pos.CENTER );
    buttons.setSpacing( 10 );
    buttons.getChildren().addAll( yesButton, noButton );
    bp.setCenter( buttons );
    HBox msg = new HBox();
    msg.setSpacing( 5 );
    msg.getChildren().addAll( icon, new Message( message ) );
    vb.getChildren().addAll( msg, bp );
    dial.showDialog();
    return buttonSelected;
}

public static void showMessageDialog( Stage owner, String message, String title ) {
    showMessageDialog( owner, new Message( message ), title );
}
public static void showMessageDialog( Stage owner, Node message, String title ) {
    VBox vb = new VBox();
    Scene scene = new Scene( vb );
    final Dialog dial = new Dialog( title, owner, scene, "res/Info.png" );
    vb.setPadding( new Inset(10,10,10,10) );
    vb.setSpacing( 10 );
    Button okButton = new Button( "OK" );
    okButton.setAlignment( Pos.CENTER );
    okButton.setOnAction( new EventHandler<ActionEvent>() {
        @Override public void handle( ActionEvent e ) {
            dial.close();
        }
    } );
    BorderPane bp = new BorderPane();
    bp.setCenter( okButton );
    HBox msg = new HBox();
    msg.setSpacing( 5 );
    msg.getChildren().addAll( icon, message );
    vb.getChildren().addAll( msg, bp );
    dial.showDialog();
}

}


1
试图运行您的类,但编译器在Layout上阻塞了-显然使用了常量。您使用了哪个导入?
likejudo 2013年

如何获得响应,即选择了哪个按钮?成员变量buttonSelected是私有的。
likejudo 2013年

得到它进行编译并使buttonSelected公开,但是像这样调用它不会显示任何内容。舞台=新舞台(StageStyle.TRANSPARENT); FXOptionPane.showConfirmDialog(stage,“您想断开连接吗?”,“我的标题”);`
likejudo 2013年

8

从此处的答案改编而成:https : //stackoverflow.com/a/7505528/921224

javafx.scene.control.Alert

有关如何使用JavaFX对话框的深入说明,请参见:code.makery的JavaFX对话框(官方)。它们比Swing对话框更强大,更灵活,并且不仅具有弹出消息的功能。

import javafx.scene.control.Alert
import javafx.scene.control.Alert.AlertType;
import javafx.application.Platform;

public class ClassNameHere
{

    public static void infoBox(String infoMessage, String titleBar)
    {
        /* By specifying a null headerMessage String, we cause the dialog to
           not have a header */
        infoBox(infoMessage, titleBar, null);
    }

    public static void infoBox(String infoMessage, String titleBar, String headerMessage)
    {
        Alert alert = new Alert(AlertType.INFORMATION);
        alert.setTitle(titleBar);
        alert.setHeaderText(headerMessage);
        alert.setContentText(infoMessage);
        alert.showAndWait();
    }
}

要记住的一件事是JavaFX是一个单线程GUI工具箱,这意味着应该直接从JavaFX应用程序线程调用此方法。如果您有另一个线程正在工作,需要对话,请参阅以下SO问答:JavaFX2:我可以暂停后台任务/服务吗?Platform.Runlater和Task Javafx

要使用此方法调用:

ClassNameHere.infoBox("YOUR INFORMATION HERE", "TITLE BAR MESSAGE");

要么

ClassNameHere.infoBox("YOUR INFORMATION HERE", "TITLE BAR MESSAGE", "HEADER MESSAGE");

1
请不要针对多个问题发布相同的答案。发布一个好的答案,然后投票/标记以将其他问题重复作为一个重复。如果问题不是重复的,请定制对问题的答案
马丁·彼得斯

1
@MartijnPieters最初的问题将Swing指定为标签,但可以打开常规Java对话框(在JavaFX真正成为现实之前就被问到了),如果我在此处发布的JavaFX内容有什么不对,但对发现问答的新手很有用在寻找Java对话框时,并没有意识到Swing已经过时。
Troyseph 2015年

那么,更多的理由就是要根据上下文量身定制答案!
马丁·彼得斯

我在Google上找到了这个主题,因此最好在这里提供信息,而不是输入问题主题以查看所需的答案。这个答案值得更多投票。
Mateus Viccari 2015年

4

从Java 8u40开始有效:

Alert alert = new Alert(AlertType.INFORMATION, "Content here", ButtonType.OK);
alert.getDialogPane().setMinHeight(Region.USE_PREF_SIZE);
alert.show();

1
请记住,这必须在FXApplicationThread中运行。(例如,具有Platform.runLater()或类似的行为)
Lerk,


2

您可以提供由JavaFX UI控件项目提供的对话框。我认为这会帮助你

Dialogs.showErrorDialog(Stage object, errorMessage,  "Main line", "Name of Dialog box");
Dialogs.showWarningDialog(Stage object, errorMessage,  "Main line", "Name of Dialog box");


javafx-dialogs-0.0.3.jar您可以下载此jar,然后可以使用相同的对话框。
Rajeev Gupta

我编辑了您的文章,以链接到Rajeev引用的第三方JavaFX对话框项目。我认为这是ControlsFX的对话框的较旧版本。
jewelsea

2
public myClass{

private Stage dialogStage;



public void msgBox(String title){
    dialogStage = new Stage();
    GridPane grd_pan = new GridPane();
    grd_pan.setAlignment(Pos.CENTER);
    grd_pan.setHgap(10);
    grd_pan.setVgap(10);//pading
    Scene scene =new Scene(grd_pan,300,150);
    dialogStage.setScene(scene);
    dialogStage.setTitle("alert");
    dialogStage.initModality(Modality.WINDOW_MODAL);

    Label lab_alert= new Label(title);
    grd_pan.add(lab_alert, 0, 1);

    Button btn_ok = new Button("fermer");
    btn_ok.setOnAction(new EventHandler<ActionEvent>() {

        @Override
        public void handle(ActionEvent arg0) {
            // TODO Auto-generated method stub
            dialogStage.hide();

        }
    });
    grd_pan.add(btn_ok, 0, 2);

    dialogStage.show();

}



}

3
至少解释一下代码在做什么可能是一个好主意。对于仅代码的答案是否可行,存在相当强烈的意见。
丹尼斯·蒙

0

要使Clairton Luz 发挥作用,您需要在中运行FXApplicationThread并将Platform.runLater代码片段插入方法:

  Platform.runLater(() -> {
                        Alert alert = new Alert(Alert.AlertType.ERROR);
                        alert.setTitle("Error Dialog");
                        alert.setHeaderText("No information.");

                        alert.showAndWait();
                    }
            );

否则,您将获得: java.lang.IllegalStateException: Not on FX application thread

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.