2017-07-07 1 views
0

私のアプリケーションでは、アプリケーションのウィンドウがフォーカスされているかどうかを知る必要があります。このために、私はprimaryStage.focusedProperty().addListener(..)を使うことができます。ステージの焦点の変化を警告します。javafx - 警告とステージフォーカス

しかし、私は(ウィンドウが現実に焦点を当てた、あるいは少なくともWindowsでされていても)所有者として、またWINDOW_MODALに設定モダリティと、このprimaryStageAlertを開くとprimaryStage緩い焦点になることを実現しています。

今私が持っている問題は、Windowがいつフォーカスされているのかを知りたいということです。primaryStageだけでなく、少なくともAlertに焦点が当てられているかどうかは分かっていますが、どのように見つけられませんでしたか?

アラートにsimilareプロパティ(onShowingonHidingなど)を使用すると、正常に機能しませんでした。

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 

またはそれに類するものです。誰もこれを達成するアイデアを持っているか、これはWINDOW_MODALAlertにフォーカスを失っていますか?

答えて

0

最後に回避策を見つけることができました。アラートに使用される各buttonTypeは、フォーカスされているかどうかを判断することができます。このプロパティは、alt + tabbingのときにも変わります。したがって、buttonTypeがすべて使用されているかどうかを監視し、1つしかフォーカスされていないかどうかを確認できます。

ここに私の解決策、少しハックが、私が望んで達成:

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()のチェックを追加することにより、ダイアログには、この方法を拡張することができると思いますが、これが出ています私の質問の範囲の。