2016-10-18 14 views
2

私はJavaFXで新しく、親ウィンドウの位置に関連した新しいウィンドウの位置の設定に問題があります。親ウィンドウの中央に新しいウィンドウを開きたいJavaFX - 親ステージへのセンターチャイルドステージ

私はこれらの二つの方法を試してみました:

1)初期の所有者 - )私は、init所有者が親の中心に私のウィンドウを開きますと思ったが、それは

FXMLLoader fxmlLoader = new  FXMLLoader(AddUserController.class.getResource("/view/addUserStage.fxml")); 
Parent root = fxmlLoader.load(); 
Stage stage = new Stage(); 
stage.initOwner(parentStage); 
stage.showAndWait(); 

2いないときのウィンドウ再配置表示されます - それは動作しますが、ウィンドウが表示された後、私はその最初の位置を見ることができ、次にそれが新しい計算位置に移動されるのを見ます。私はそれを受け入れることができません。 onWindowShown機能で

FXMLLoader fxmlLoader = new  FXMLLoader(AddUserController.class.getResource("/view/addUserStage.fxml")); 
Parent root = fxmlLoader.load(); 
Stage stage = new Stage(); 
stage.initOwner(parentStage); 
stage.setOnShown(event -> controller.onWindowShown()); 
stage.showAndWait(); 

後にのみ幅と私の窓の高さが示されたので、私は、新しいXと私の窓のY位置を設定していますが知られており、私がイースリー新しい位置を算出することができます。

showAndWait関数の前に、親ウィンドウの中央に子ウィンドウの位置を設定するにはどうすればよいですか?

答えて

2

Stageを表示する場合は、FXMLファイルからロードされたコンテンツをSceneに配置する必要があり、SceneStageに設定されます。

残念ながらStageのサイズはレンダリングされるまではわかりませんが(前述のように)、親の中心に移動するにはStageのサイズを知る必要があります。

これは、表示される前にhideStageに送信され、再配置され、次に新しい位置にmake it visibleが表示されます。

public class Main extends Application { 
    @Override 
    public void start(Stage primaryStage) { 
     try { 
      BorderPane root = new BorderPane(); 
      Scene scene = new Scene(root, 400, 400); 

      Button button = new Button("Open another Stage"); 
      button.setOnAction(e -> { 

       Stage popUpStage = new Stage(); 

       // Here add the FXML content to the Scene 
       Scene popUpScene = new Scene(new Button()); 
       popUpStage.setScene(popUpScene); 

       // Calculate the center position of the parent Stage 
       double centerXPosition = primaryStage.getX() + primaryStage.getWidth()/2d; 
       double centerYPosition = primaryStage.getY() + primaryStage.getHeight()/2d; 

       // Hide the pop-up stage before it is shown and becomes relocated 
       popUpStage.setOnShowing(ev -> popUpStage.hide()); 

       // Relocate the pop-up Stage 
       popUpStage.setOnShown(ev -> { 
        popUpStage.setX(centerXPosition - popUpStage.getWidth()/2d); 
        popUpStage.setY(centerYPosition - popUpStage.getHeight()/2d); 
        popUpStage.show(); 
       }); 

       popUpStage.showAndWait(); 
      }); 

      root.setCenter(button); 


      primaryStage.setScene(scene); 
      primaryStage.show(); 
     } catch(Exception e) { 
      e.printStackTrace(); 
     } 
    } 

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

あなたはStageを表示する前にSceneをレイアウトし、Sceneサイズに基づいて位置を決定することができます。しかし、これは考慮にウィンドウの装飾になりませんので、あなたのアカウントにこれらの装飾の大きさを取るために装飾の同じ種類を持つウィンドウを持っていない限り、位置が少しずれが考えられます。他の回答として

@Override 
public void start(Stage primaryStage) { 
    Button btnMain = new Button("show"); 
    btnMain.setOnAction(evt -> { 
     Stage stage = new Stage(); 
     Button btn = new Button("Close"); 
     btn.setOnAction((ActionEvent event) -> { 
      stage.close(); 
     }); 

     StackPane root = new StackPane(); 
     root.getChildren().add(btn); 

     Bounds mainBounds = primaryStage.getScene().getRoot().getLayoutBounds(); 
     Scene scene = new Scene(root, 400, 400); 

     stage.setScene(scene); 

     // layout new scene 
     scene.getRoot().applyCss(); 
     scene.getRoot().layout(); 

     Bounds rootBounds = scene.getRoot().getLayoutBounds(); 
     stage.setX(primaryStage.getX() + (mainBounds.getWidth() - rootBounds.getWidth())/2); 
     stage.setY(primaryStage.getY() + (mainBounds.getHeight() - rootBounds.getHeight())/2); 
     stage.showAndWait(); 
     System.out.println("done"); 
    }); 
    Scene mainScene = new Scene(new StackPane(btnMain), 600, 600); 
    primaryStage.setScene(mainScene); 
    primaryStage.show(); 
} 
+0

。 – scoozi17

2

を正しく記述すると、ウィンドウが表示されているときにJavaFXがステージの幅と高さを計算します。 onShowing()プロパティは、計算が実行される前、およびウィンドウが可視に設定される前に呼び出されるため、実際にはstage.hide()コマンドを配置すると何も起こりません。質問が述べるように、ウィンドウが再配置される直前に画面上で瞬きを見ることは、あまり望ましい結果ではありません。

この問題を解決するために私が見つけた唯一の方法は、ステージの幅と高さのプロパティにリスナーを追加し、イベントを発生させてウィンドウの位置。その後、ウィンドウが表示されたら、リスナーを削除します。例えば

:私は前に境界を取得leayout機能を行う場合でも、ルートの境界でゼロを取得する理由が、私は知らない

//Let's say we want to center the new window in the parent window 

ChangeListener<Number> widthListener = (observable, oldValue, newValue) -> { 
     double stageWidth = newValue.doubleValue(); 
     stage.setX(parentStage.getX() + parentStage.getWidth()/2 - stageWidth/2); 
}; 
ChangeListener<Number> heightListener = (observable, oldValue, newValue) -> { 
     double stageHeight = newValue.doubleValue(); 
     stage.setY(parentStage.getY() + parentStage.getHeight()/2 - stageHeight/2); 
}; 

stage.widthProperty().addListener(widthListener); 
stage.heightProperty().addListener(heightListener); 

//Once the window is visible, remove the listeners 
stage.setOnShown(e -> { 
    stage.widthProperty().removeListener(widthListener); 
    stage.heightProperty().removeListener(heightListener); 
}); 

stage.show(); 
+0

これは私にとってうまくいった。私は信じられませんが、setLocationRelativeTo(something)のようなメソッドは含まれていませんでした。 –

関連する問題