2015-10-03 44 views
6

JavaFXで現在開いているステージを取得する方法はありますか?このようなJavaFXで現在開かれているステージを取得する方法は?

何か:

Stage newStage = new Stage(); 
newStage.initOwner(JavaFx.getCurrentOpenedStage()); //Like this 
+1

AFAIKこれを行う方法はありません。これのコンテキストは何ですか?おそらく、あなたが望むことをするための別の方法があります。これがユーザーの操作に応答している場合は、常に 'node.getScene()。getWindow()'でノードを含むウィンドウを取得できます。 –

+0

通知は、スレッド内の「無限ループ」内に表示されます。このスレッドでは、ユーザーがシステムにログインしてもスレッドが実行を継続した後に閉じる最初のアプリケーションウィンドウ(ログインウィンドウ)からスレッドが開始されるため、どのウィンドウも参照していません。 –

答えて

9

このための組み込み機能はありません。ほとんどの場合、ユーザーアクションの結果として新しいStageを開くので、アクションが発生したノードでgetScene().getWindow()を呼び出して、「現在の」ウィンドウを取得できます。

他の使用例では、現在のウィンドウを自分で追跡するコードを記述する必要があります。もちろん、複数のウィンドウが開いている可能性がありますので、何らかのコレクションでそれらを追跡する必要があります。ステージを管理したり、ステージの開閉にイベントハンドラを登録するためのファクトリクラスを作成して、プロパティやリストを更新することをお勧めします。あなたはおそらくこれをシングルトンにしたいと思うでしょう。ここでは実装の例を示します:getOpenStages()は、開いているステージの目に見えるリストを示します。最後のものは最近開いたものです。currentStageProperty()はフォーカスされたステージを示します。正確なニーズに応じて、実装が異なる場合があります。

public enum StageFactory { 
    INSTANCE ; 

    private final ObservableList<Stage> openStages = FXCollections.observableArrayList(); 

    public ObservableList<Stage> getOpenStages() { 
     return openStages ; 
    } 

    private final ObjectProperty<Stage> currentStage = new SimpleObjectProperty<>(null); 
    public final ObjectProperty<Stage> currentStageProperty() { 
     return this.currentStage; 
    } 
    public final javafx.stage.Stage getCurrentStage() { 
     return this.currentStageProperty().get(); 
    } 
    public final void setCurrentStage(final javafx.stage.Stage currentStage) { 
     this.currentStageProperty().set(currentStage); 
    } 

    public void registerStage(Stage stage) { 
     stage.addEventHandler(WindowEvent.WINDOW_SHOWN, e -> 
       openStages.add(stage)); 
     stage.addEventHandler(WindowEvent.WINDOW_HIDDEN, e -> 
       openStages.remove(stage)); 
     stage.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> { 
      if (isNowFocused) { 
       currentStage.set(stage); 
      } else { 
       currentStage.set(null); 
      } 
     }); 
    } 

    public Stage createStage() { 
     Stage stage = new Stage(); 
     registerStage(stage); 
     return stage ; 
    } 

} 

(注)この唯一のあなたはとてもあなたのコードがその要件と協力しなければ、StageFactory.INSTANCE.createStage()から入手したか、別の場所に作成され、StageFactory.INSTANCE.registerStage(...)メソッドに渡されたステージを追跡することができます。一方、ステージを初期化するコードを集中化する機会を提供しますが、これは他の点で有益です。ここで

はこれを使って簡単な例です:

import javafx.application.Application; 
import javafx.beans.property.ObjectProperty; 
import javafx.beans.property.SimpleObjectProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.Label; 
import javafx.scene.layout.VBox; 
import javafx.stage.Stage; 
import javafx.stage.WindowEvent; 

public class SceneTrackingExample extends Application { 

    int count = 0 ; 

    @Override 
    public void start(Stage primaryStage) { 
     StageFactory factory = StageFactory.INSTANCE ; 
     factory.registerStage(primaryStage); 

     configureStage(primaryStage); 
     primaryStage.show(); 
    } 

    private void configureStage(Stage stage) { 
     StageFactory stageFactory = StageFactory.INSTANCE; 
     Stage owner = stageFactory.getCurrentStage() ; 
     Label ownerLabel = new Label(); 
     if (owner == null) { 
      ownerLabel.setText("No owner"); 
     } else { 
      ownerLabel.setText("Owner: "+owner.getTitle()); 
      stage.initOwner(owner); 
     } 
     stage.setTitle("Stage "+(++count)); 
     Button newStage = new Button("New Stage"); 
     newStage.setOnAction(e -> { 
      Stage s = stageFactory.createStage(); 
      Stage current = stageFactory.getCurrentStage() ; 
      if (current != null) { 
       s.setX(current.getX() + 20); 
       s.setY(current.getY() + 20); 
      } 
      configureStage(s); 
      s.show(); 
     }); 

     VBox root = new VBox(10, ownerLabel, newStage); 
     root.setAlignment(Pos.CENTER); 
     stage.setScene(new Scene(root, 360, 150)); 
    } 

    public enum StageFactory { 
     INSTANCE ; 

     private final ObservableList<Stage> openStages = FXCollections.observableArrayList(); 

     public ObservableList<Stage> getOpenStages() { 
      return openStages ; 
     } 

     private final ObjectProperty<Stage> currentStage = new SimpleObjectProperty<>(null); 
     public final ObjectProperty<Stage> currentStageProperty() { 
      return this.currentStage; 
     } 
     public final javafx.stage.Stage getCurrentStage() { 
      return this.currentStageProperty().get(); 
     } 
     public final void setCurrentStage(final javafx.stage.Stage currentStage) { 
      this.currentStageProperty().set(currentStage); 
     } 

     public void registerStage(Stage stage) { 
      stage.addEventHandler(WindowEvent.WINDOW_SHOWN, e -> 
        openStages.add(stage)); 
      stage.addEventHandler(WindowEvent.WINDOW_HIDDEN, e -> 
        openStages.remove(stage)); 
      stage.focusedProperty().addListener((obs, wasFocused, isNowFocused) -> { 
       if (isNowFocused) { 
        currentStage.set(stage); 
       } else { 
        currentStage.set(null); 
       } 
      }); 
     } 

     public Stage createStage() { 
      Stage stage = new Stage(); 
      registerStage(stage); 
      return stage ; 
     } 

    } 

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

のJava 9はjavafx.stage.Window.getWindows()法を添加することによって、これが可能になります。したがって、あなたは単にWindowsのリストを取得して表示することができます

List<Window> open = Stage.getWindows().filtered(window -> window.isShowing());