Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
javafx-警报和舞台焦点_Java_Javafx_Focus_Javafx 8_Alert - Fatal编程技术网

javafx-警报和舞台焦点

javafx-警报和舞台焦点,java,javafx,focus,javafx-8,alert,Java,Javafx,Focus,Javafx 8,Alert,对于我的应用程序,我需要知道应用程序的窗口是否被聚焦。为此,我可以使用primaryStage.focusedProperty().addListener(..),这将警告我阶段焦点的更改 但我已经意识到,以该primaryStage作为所有者并将模态设置为WINDOW\u MODAL打开Alert会使primaryStage失去焦点(即使该窗口实际上是焦点,或者至少是在Windows中) 现在我遇到的问题是,我想知道窗口何时聚焦,而不仅仅是初级阶段;或者至少知道警报是否被聚焦,但我找不到如何聚

对于我的应用程序,我需要知道应用程序的窗口是否被聚焦。为此,我可以使用
primaryStage.focusedProperty().addListener(..)
,这将警告我阶段焦点的更改

但我已经意识到,以该
primaryStage
作为所有者并将模态设置为
WINDOW\u MODAL
打开
Alert
会使
primaryStage
失去焦点(即使该窗口实际上是焦点,或者至少是在Windows中)

现在我遇到的问题是,我想知道
窗口
何时聚焦,而不仅仅是
初级阶段
;或者至少知道
警报
是否被聚焦,但我找不到如何聚焦

我尝试在警报上使用类似的属性(如
显示
隐藏
),但没有成功

下面是一段代码来说明我的问题:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));

        primaryStage.focusedProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("primaryStage focused : "+newValue);
        });
        primaryStage.show();

        //create a basic alert
        Alert alert = new Alert(Alert.AlertType.INFORMATION,"This is a test");
        alert.initModality(Modality.WINDOW_MODAL); //will block input to its owner window
        alert.initOwner(primaryStage);
        alert.onShowingProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("alert onShowing : "+newValue);
        });
        alert.onShownProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("alert onShown : "+newValue);
        });
        alert.onHidingProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("alert onHiding : "+newValue);
        });
        alert.onHiddenProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("alert onHidden : "+newValue);
        });
        alert.showAndWait();
    }


    public static void main(String[] args) {
        launch(args);
    }
}
基本上,它将打印以下内容:

primaryStage focused : true //stage is created and displayed
primaryStage focused : false //alert is displayed, stage loses focus. alt+tab changes nothing
primaryStage focused : true //alert closed by pressing 'ok'
这很奇怪,因为所有其他的印刷品,它应该产生。 理想情况下,我还需要:

primaryStage focused : true //stage is created and displayed
primaryStage focused : false //alert is displayed, stage loses focus
alert focused : true //alert gains focus
alert focused : false //alt+tab to an other window
alert focused : true //alt+tab back to this window
alert focused : false //alert closed by pressing 'ok'
primaryStage focused : true //stage regains focus

或者类似的东西。是否有人有想法实现这一点,或者这是
primaryStage
失去了对
窗口模式的关注
警报
一个我应该报告的问题?

因此我最终可以找到解决办法。警报中使用的每个
按钮类型
都可以确定它是否处于焦点状态。alt+tabbing时此属性也会更改,因此我们可以监视使用的每个
buttonType
,并查看是否只有一个被聚焦

这里是我的解决方案,有点老套,但实现了我想要的:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));

        primaryStage.focusedProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("PrimaryStage focused : "+newValue);
        });
        primaryStage.show();

        //create a basic alert
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION,"This is a test");
        alert.initModality(Modality.WINDOW_MODAL); //will block input to its owner window
        alert.initOwner(primaryStage);

        alert.getButtonTypes().forEach(buttonType -> {
            //add a focus listnener for each buttonType of this alert
            alert.getDialogPane().lookupButton(buttonType).focusedProperty().addListener((observable, oldValue, newValue) -> {
                System.out.println(buttonType.getText()+" focused : "+newValue);
                System.out.println("Alert focused : "+isAlertFocused(alert));

            });
        });
        alert.showAndWait();
    }

    /** Looks all {@link ButtonType} used in the given {@link Alert} and checks if any of them is
     * focused, hence if the {@link Alert} is being focused
     *
     * @param alert the {@link Alert} we want to check the focused status from
     * @return true if the alert is focused, false otherwise
     */
    private boolean isAlertFocused(Alert alert){
        if(alert == null){
            return false;
        }

        final boolean[] focused = {false};
        alert.getButtonTypes().forEach(buttonType -> {
            focused[0] = focused[0] || alert.getDialogPane().lookupButton(buttonType).isFocused();
        });
        return focused[0];
    }


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

我想我还可以通过在
isAlertFocused(alert-alert)
方法中添加对
alert.getDialogPane().isFocused()
的检查来将此方法扩展到dialog,但这超出了我的问题范围

所以我终于找到了解决办法。警报中使用的每个
按钮类型
都可以确定它是否处于焦点状态。alt+tabbing时此属性也会更改,因此我们可以监视使用的每个
buttonType
,并查看是否只有一个被聚焦

这里是我的解决方案,有点老套,但实现了我想要的:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.stage.Modality;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");
        primaryStage.setScene(new Scene(root, 300, 275));

        primaryStage.focusedProperty().addListener((observable, oldValue, newValue) -> {
            System.out.println("PrimaryStage focused : "+newValue);
        });
        primaryStage.show();

        //create a basic alert
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION,"This is a test");
        alert.initModality(Modality.WINDOW_MODAL); //will block input to its owner window
        alert.initOwner(primaryStage);

        alert.getButtonTypes().forEach(buttonType -> {
            //add a focus listnener for each buttonType of this alert
            alert.getDialogPane().lookupButton(buttonType).focusedProperty().addListener((observable, oldValue, newValue) -> {
                System.out.println(buttonType.getText()+" focused : "+newValue);
                System.out.println("Alert focused : "+isAlertFocused(alert));

            });
        });
        alert.showAndWait();
    }

    /** Looks all {@link ButtonType} used in the given {@link Alert} and checks if any of them is
     * focused, hence if the {@link Alert} is being focused
     *
     * @param alert the {@link Alert} we want to check the focused status from
     * @return true if the alert is focused, false otherwise
     */
    private boolean isAlertFocused(Alert alert){
        if(alert == null){
            return false;
        }

        final boolean[] focused = {false};
        alert.getButtonTypes().forEach(buttonType -> {
            focused[0] = focused[0] || alert.getDialogPane().lookupButton(buttonType).isFocused();
        });
        return focused[0];
    }


    public static void main(String[] args) {
        launch(args);
    }
}
我想我还可以通过在
isAlertFocused(alert-alert)
方法中添加对
alert.getDialogPane().isFocused()
的检查来将此方法扩展到dialog,但这超出了我的问题范围