如果所有者最小化,则Javafx对话框(警报)不可见

时间:2016-04-28 09:30:15

标签: java javafx dialog javafx-8

如果所有者最小化,为什么javafx中的对话(警报)未正确显示。

查看以下代码:

public class JavaFxSample2 extends Application {

@Override
public void start(Stage primaryStage) throws InterruptedException, ExecutionException {
    primaryStage.setTitle("open alert in 2 seconds");
    Pane pane = new Pane();
    Button b = new Button("open dialog");
    b.setOnMouseClicked(event -> {
        Task<Void> task = new Task<Void>() {
            @Override
            protected Void call() throws Exception {
                Thread.sleep(2000);
                return null;
            }
        };
        task.stateProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue == State.SUCCEEDED) {
                Alert alert = new Alert(AlertType.INFORMATION, "Hello");
                alert.initOwner(primaryStage);                  
                alert.showAndWait();
            }
        });
        Thread thread = new Thread(task);
        thread.start();
    });

    pane.getChildren().add(b);

    Scene scene = new Scene(pane, 300, 275);
    primaryStage.setScene(scene);
    primaryStage.show();
}

public static void main(String[] args) {
    launch(args);
}
}

如果你在2秒内最小化应用程序,然后再次最大化(2秒后)你没有看到对话框,但它以某种方式存在(舞台被锁定,直到你按esc或输入)

如果您没有最小化舞台,则会正确显示对话框。

这是一个错误吗?我做错了吗?

编辑: 系统是Windows 7,Java 1.8.0.66

EDIT2: 好。它似乎真的是一个错误: https://bugs.openjdk.java.net/browse/JDK-8151170

4 个答案:

答案 0 :(得分:5)

找到(可能的)解决方案。 但这真的是一个很好的解决方案吗?

在显示警报之前

执行以下行:

((Stage) alert.getOwner()).setIconified(false);

如果有人有更好的主意我会删除我的答案。

答案 1 :(得分:1)

这是一个静态方法,嵌入了@ Lurking Elk的先前技巧。

它会自动执行该过程,然后将父级恢复为其当前的“已图标化”状态。

public static <T> Optional< T > Dialog_showAndWait( Dialog< T > _dialog )
{
    /**
     * a) PATCH:
     *      IF( dialog.Parent is iconified )
     *      THEN de-iconify the Parent
     */
    Boolean isParentIconized = null;
    Stage   parentStage = ( (Stage) _dialog.getOwner() );
    if( parentStage != null )
    {
        isParentIconized = parentStage.isIconified();
        if( isParentIconized )
            parentStage.setIconified( false );
    }

    /**
     * b) Process the original function
     */
    Optional< T > result = _dialog.showAndWait();

    /**
     * c) Restore the initial state of the dialog's Parent
     */
    if( parentStage != null )
    if( isParentIconized )
        parentStage.setIconified( isParentIconized );

    return result;
}

答案 2 :(得分:0)

如果您在显示提醒对话框之前添加此语句,则无需按EscEnter。这将使您免于冻结您的应用。

alert.initModality(Modality.NONE);

答案 3 :(得分:0)

    DaoAlloyGeneral a = (DaoAlloyGeneral) tabelaAlloy.getSelectionModel().getSelectedItem();
            Alert alert = new Alert(AlertType.CONFIRMATION);
            alert.setTitle(DaoCfgIdiomas.getTraducao("general.Confirmacao"));
            alert.setHeaderText(DaoCfgIdiomas.getTraducao("general.Atencao"));
            alert.setContentText(DaoCfgIdiomas.getTraducao("MainTabAlloy.msgDeletar") + " " +a.getNome());
            alert.setResizable(true);
            alert.getDialogPane().setPrefSize(480, 320);
            Optional<ButtonType> result = alert.showAndWait();
            if (result.get() == ButtonType.OK){

                DaoAlloyGeneral.deletarAlloy(a.getIdAlloy());
                tabelaAlloy.getItems().clear();
                tabelaAlloy.setItems(DaoAlloyGeneral.buscaTodos());
            }

enter image description here

我无法理解它之前和现在都有效,停止。 Oracle jdk1.8.0_111 linux机器

编辑:我发现了问题,JVM参数 - Dcom.sun.javafx.isEmbedded = true 没有这个选项就可以了。