Events 防止多窗口,并在失去焦点时关闭窗口JAVAFX

Events 防止多窗口,并在失去焦点时关闭窗口JAVAFX,events,javafx,window,project,Events,Javafx,Window,Project,我正在构建一个javafx应用程序,其中有一个更改密码的按钮,对于这个操作,我希望加载一个新的更改密码FXML。这很简单,我知道,但我的问题是,每次点击按钮,就会打开一个新的更改密码窗口。或者有没有一种方法可以在“更改密码”窗口失去焦点时关闭它,即如果我单击其他任何地方 @FXML private void CPassBtn(ActionEvent event) { try { Parent part = FXMLLoader.load(getClass().ge

我正在构建一个javafx应用程序,其中有一个更改密码的按钮,对于这个操作,我希望加载一个新的更改密码FXML。这很简单,我知道,但我的问题是,每次点击按钮,就会打开一个新的更改密码窗口。或者有没有一种方法可以在“更改密码”窗口失去焦点时关闭它,即如果我单击其他任何地方

@FXML
private void CPassBtn(ActionEvent event) {

  try 
    {
        Parent part = FXMLLoader.load(getClass().getResource("/EmpSalary/ui/Mainwin/forChangePass.fxml"));
        Stage stage = new Stage();
        stage.setResizable(false);
        stage.getIcons().add(new Image("/resources/letter.png"));
        stage.setScene(new Scene(part));

        stage.setTitle("Password change");
        stage.show();

    }
    catch (IOException ex) {
        Logger.getLogger(LoginuiController.class.getName()).log(Level.SEVERE, null, ex);
    }
}

不完全是您描述的功能,但使用模态可能会起作用(它会阻止所有者或应用程序根据模态处理输入事件):


可以使用布尔值阻止多个窗口,以检查是否已加载

    private boolean stageLoaded = false ;


  @FXML private void CPassBtn(ActionEvent event) {

   try 
{ 
    if(stageLoaded){ return;}
    Parent part = FXMLLoader.load(getClass().getResource("/EmpSalary/ui/Mainwin/forChangePass.fxml"));
    Stage stage = new Stage();
    stage.setResizable(false);
    stage.getIcons().add(new Image("/resources/letter.png"));
    stage.setScene(new Scene(part));

    stage.setTitle("Password change");
    stage.show();

    stageLoaded = true ;
}
catch (IOException ex) {
    Logger.getLogger(LoginuiController.class.getName()).log(Level.SEVERE, null, ex);
}
}
但是如果需要再次将stageLoaded设置为false。您需要添加一个event stage.setOnCloseRequest

private boolean stageLoaded = false ;


   @FXML private void CPassBtn(ActionEvent event) {

   try 
{ 
if(stageLoaded){ return;}
Parent part =FXMLLoader.load(getClass().getResource("/EmpSalary/ui/Mainwin/forChangePa 
ss.fxml"));
Stage stage = new Stage();
stage.setResizable(false);
stage.getIcons().add(new Image("/resources/letter.png"));
stage.setScene(new Scene(part));

stage.setTitle("Password change");
stage.show();

stageLoaded = true ;
 stage.setOnCloseRequest((WindowEvent even) -> {
                stageLoaded = false;

}
 catch (IOException ex) {
Logger.getLogger(LoginuiController.class.getName()).log(Level.SEVERE, 
 null, ex);
 }
 }

我想这正是你想要的

stage.focusedProperty().addListener(new ChangeListener<Boolean>()
{
  @Override
  public void changed(ObservableValue<? extends Boolean> b, Boolean oldValue, Boolean newValue)
  {
    if(newValue == false)
        stage.close();
  }
});
stage.focusedProperty().addListener(新的ChangeListener())
{
@凌驾

公共无效已更改(ObservableValue此解决方案检查焦点何时更改,如果舞台失去焦点则关闭

public class Main extends Application {

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

    @Override
    public void start(Stage primaryStage) {
        Button button = new Button("Password Window");

        Scene scene = new Scene(button);
        primaryStage.setScene(scene);
        primaryStage.show();

        button.setOnAction(event -> System.out.println(openPasswordWindow()));
    }

    private String openPasswordWindow(){
        PasswordField passwordField = new PasswordField();
        Stage stage = new Stage(StageStyle.UTILITY);
        stage.setScene(new Scene(passwordField));
        stage.show();

        //You would need from here 
        stage.focusedProperty().addListener((ov, onHidden, onShown) -> {
            if(!stage.isFocused())
                Platform.runLater(() -> stage.close());
        });
        //Down to here

        return passwordField.getText();
    }
}
在您的代码中,它将如下所示

@FXML
private void CPassBtn(ActionEvent event) {

    try
    {
        Parent part = FXMLLoader.load(getClass().getResource("/EmpSalary/ui/Mainwin/forChangePass.fxml"));
        Stage stage = new Stage();
        stage.setResizable(false);
        stage.getIcons().add(new Image("/resources/letter.png"));
        stage.setScene(new Scene(part));

        stage.setTitle("Password change");
        stage.show();

        stage.focusedProperty().addListener((ov, onHidden, onShown) -> {
            if(!stage.isFocused())
                Platform.runLater(() -> stage.close());
        });
    }
    catch (IOException ex) {
        Logger.getLogger(LoginuiController.class.getName()).log(Level.SEVERE, null, ex);
    }
}

与您的问题无关:请学习java命名约定并坚持它们。相关:无论是否允许打开changeDialog,您都需要一个具有布尔属性的模型层,然后将按钮的禁用绑定到该属性。谢谢您纠正我,从现在起我一定会遵循java命名约定。非常感谢您ch.和所有其他人,我也是新手,如果我第一次使用javafx时在我的代码中犯了任何错误,很抱歉。你能告诉我我做错了什么吗?特别是在我的回答中。我不知道“非常规命名”。谢谢
@FXML
private void CPassBtn(ActionEvent event) {

    try
    {
        Parent part = FXMLLoader.load(getClass().getResource("/EmpSalary/ui/Mainwin/forChangePass.fxml"));
        Stage stage = new Stage();
        stage.setResizable(false);
        stage.getIcons().add(new Image("/resources/letter.png"));
        stage.setScene(new Scene(part));

        stage.setTitle("Password change");
        stage.show();

        stage.focusedProperty().addListener((ov, onHidden, onShown) -> {
            if(!stage.isFocused())
                Platform.runLater(() -> stage.close());
        });
    }
    catch (IOException ex) {
        Logger.getLogger(LoginuiController.class.getName()).log(Level.SEVERE, null, ex);
    }
}