自定义退出并最小化JavaFX意外问题

时间:2017-09-26 23:09:32

标签: java macos user-interface javafx operating-system

所以我有两种退出应用程序的方法,我创建的按钮和我创建的键绑定。

我遇到的问题是最小化。对于按钮,我在初始启动时单击它,它不起作用。我第二次点击它,它将工作。这是按钮的代码。

@FXML
public void minimizeClick() {
    minimizeButton.setOnAction(e ->
            ( (Stage) ( (Button) e.getSource() ).getScene().getWindow() ).setIconified(true)
    );
}

现在对于键绑定,当我在Mac OS上按CMD + M时,它将首次运行。当我在同一个会话中再次启动应用程序时,它会口吃。因此,我必须两次使用键绑定组合来执行操作。这是代码:

    scene.setOnKeyPressed(e -> {
        if(e.getCode() == KeyCode.COMMAND) {
            detW = true;
            detM = true;
        }
        if(detW && e.getCode() == KeyCode.W) {
            System.exit(0);
            detW = false;
        }
        else if(detM && e.getCode() == KeyCode.M) {
            primaryStage.setIconified(true);
            detM = false;
        }
    });

第三个条件处理最小化。该方法也处理退出程序,但显然我至少只能退出程序一次。将来我将终止映射到CMD + Q而不是CMD + W.

为什么这不起作用?

1 个答案:

答案 0 :(得分:1)

您没有发布您的FXML文件,但我会假设您有类似的内容

<Button text="..." fx:id="minimizeButton" onAction="#minimizeClick" />

在其中。

按钮有一个名为onAction的属性,类型为EventHandler<ActionEvent>。如果单击该按钮(或以其他方式触发,例如通过键盘),则如果onAction不为空,则执行该按钮。

onAction="#minimizeClick"onAction属性设置为EventHandler,调用控制器中定义的minimizeClick()方法。

因此,您可以将所有这些视为&#34;当单击按钮时,在控制器中调用minimizeClick()&#34;

您的minimizeClick()方法是这样的:

@FXML
public void minimizeClick() {
    minimizeButton.setOnAction(e ->
            ( (Stage) ( (Button) e.getSource() ).getScene().getWindow() ).setIconified(true)
    );
}

此方法的作用是将按钮的onAction属性设置为新的处理程序;即它用一个新的处理程序(最小化窗口)替换当前的onAction处理程序。

因此,第一次单击该按钮时,将调用minimizeClick()。这将使用新的处理程序替换当前的onAction处理程序(调用minimizeClick())。

单击按钮的第二个(以及任何后续)时间,将调用新安装的onAction处理程序,从而最小化窗口。

因此,您实际看到的行为是在第一次按键单击时没有任何反应,但在第二个按钮上单击窗口最小化。

如果您没有使用FXML(仅限Java),那么您的代码将等同于

minimizeButton.setOnAction(e1 -> {
    minimizeButton.setOnAction(e2 -> {
        ((Stage)((Button)e2.getSource()).getScene().getWindow()).setIconified(true);
    });
});

显然,您只需要一个简单的处理程序来最小化按钮,即您希望minimizeClick()方法最小化窗口。所以你需要

@FXML
public void minimizeClick() {
    ( (Stage) ( (Button) e.getSource() ).getScene().getWindow() ).setIconified(true);
}

我不明白你的意思&#34;当我再次提起应用程序时,它会断断续续地#34;但听起来这与你发布的代码无关。对于您的关键事件处理程序,您应该使用KeyEvent.isShortcutDown()等来查看按下感兴趣的键时是否按下 cmd 键,而不是尝试自己跟踪它。即尝试

scene.setOnKeyPressed(e -> {
    if(e.getCode() == KeyCode.W && e.isShortcutDown()) {
        System.exit(0);
        // Aside: you should really use Platform.exit() instead of System.exit(0)
        // as it will gracefully shutdown the FX toolkit and ensure your
        // Application's stop() method is called, etc.
    } else if(e.getCode() == KeyCode.M && e.isShortcutDown()) {
        primaryStage.setIconified(true);
    }
});

请注意,Mac上 cmd - M 的默认(本机操作系统)行为是为了最小化窗口,因此这可能会使您观察到的行为混淆。 (即我认为在Mac上,这种行为可能在没有任何这些关键处理程序的情况下发生。)