2012-10-09 15 views
10

ちょっとネットを検索しましたが、次の問題を解決できませんでした。コントローラクラスのjavafxアプリケーションで画面をスワップする方法は?

javafxには3つの基本ファイルがあります。コントローラークラス、fxmlファイル、およびアプリケーションクラスです。今私はコントローラでボタンをクリックして(完全に正常に動作します)、そのクリック(通常はstage.setScreen()で行う)の画面を変更したいのですが、私はステージへの参照を持っていませんアプリケーションクラスで見つけることができます)。

アプリケーションサンプル:

public class JavaFXApplication4 extends Application { 

@Override 
public void start(Stage stage) throws Exception { 
    Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml")); 

    Scene scene = new Scene(root); 

    stage.setScene(scene); 
    stage.show(); 
} 

/** 
* The main() method is ignored in correctly deployed JavaFX application. 
* main() serves only as fallback in case the application can not be 
* launched through deployment artifacts, e.g., in IDEs with limited FX 
* support. NetBeans ignores main(). 
* 
* @param args the command line arguments 
*/ 
public static void main(String[] args) { 
    launch(args); 
} 
} 

FXML-サンプル:

<?xml version="1.0" encoding="UTF-8"?> 

<?import java.lang.*?> 
<?import java.util.*?> 
<?import javafx.scene.*?> 
<?import javafx.scene.control.*?> 
<?import javafx.scene.layout.*?> 

<AnchorPane id="AnchorPane" prefHeight="200.0" prefWidth="320.0" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication4.SampleController"> 
    <children> 
    <Button id="button" fx:id="nextScreen" layoutX="126.0" layoutY="90.0" onAction="#handleButtonAction" text="Next Screen" /> 
    <Label fx:id="label" layoutX="126.0" layoutY="120.0" minHeight="16.0" minWidth="69.0" /> 
    </children> 
</AnchorPane> 

コントローラー-サンプル:

public class SampleController implements Initializable { 

@FXML 
private Label label; 

@FXML 
private void handleButtonAction(ActionEvent event) { 
    System.out.println("You clicked me!"); 
    label.setText("Hello World!"); 
    //Here I want to swap the screen! 
} 

@Override 
public void initialize(URL url, ResourceBundle rb) { 
    // TODO 
}  
} 

私は助けの任意の種類のために感謝するでしょう。

答えて

18
@FXML 
private void handleButtonAction(ActionEvent event) { 
    System.out.println("You clicked me!"); 
    label.setText("Hello World!"); 
    //Here I want to swap the screen! 

    Stage stageTheEventSourceNodeBelongs = (Stage) ((Node)event.getSource()).getScene().getWindow(); 
    // OR 
    Stage stageTheLabelBelongs = (Stage) label.getScene().getWindow(); 
    // these two of them return the same stage 
    // Swap screen 
    stage.setScene(new Scene(new Pane())); 
} 
+0

ありがとうございました。私が探していたものです。 –

+0

非常に参考になった!ありがとう:) –

0

この古い質問は、Javaになって同じ問題を解決しようとしています。 シーン間でスイッチを切り替えるときに、スイッチを再びインスタンス化する(以前の状態を失う)ので、スイッチ間のコンテンツをシーンに記憶させたいので、受け入れられた答えを使用できませんでした。

とにかく受け入れられた答えとanswer to the similar questionは、状態を失うことなくシーンを切り替える方法についてのヒントを与えました。 主なアイデアは、シーンのインスタンスを別のコントローラに挿入することです。コントローラは新しいシーンを何度も繰り返しインスタンス化する必要はありませんが、既存のインスタンスをそのまま使用することができます。

public class Main extends Application { 

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

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     // getting loader and a pane for the first scene. 
     // loader will then give a possibility to get related controller 
     FXMLLoader firstPaneLoader = new FXMLLoader(getClass().getResource("firstLayout.fxml")); 
     Parent firstPane = firstPaneLoader.load(); 
     Scene firstScene = new Scene(firstPane, 300, 275); 

     // getting loader and a pane for the second scene 
     FXMLLoader secondPageLoader = new FXMLLoader(getClass().getResource("secondLayout.fxml")); 
     Parent secondPane = secondPageLoader.load(); 
     Scene secondScene = new Scene(secondPane, 300, 275); 

     // injecting second scene into the controller of the first scene 
     FirstController firstPaneController = (FirstController) firstPaneLoader.getController(); 
     firstPaneController.setSecondScene(secondScene); 

     // injecting first scene into the controller of the second scene 
     SecondController secondPaneController = (SecondController) secondPageLoader.getController(); 
     secondPaneController.setFirstScene(firstScene); 

     primaryStage.setTitle("Switching scenes"); 
     primaryStage.setScene(firstScene); 
     primaryStage.show(); 
    } 
} 

そして、ここにある、両方のコントローラ:だからここ

シーンインスタンス化するメインクラスです

public class FirstController { 

    private Scene secondScene; 

    public void setSecondScene(Scene scene) { 
     secondScene = scene; 
    } 

    public void openSecondScene(ActionEvent actionEvent) { 
     Stage primaryStage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow(); 
     primaryStage.setScene(secondScene); 
    } 
} 

うん、二番目は同じに見えますが(いくつかのロジックは、おそらく共有できます現在の状態は概念の証明として十分です)

public class SecondController { 

    private Scene firstScene; 

    public void setFirstScene(Scene scene) { 
     firstScene = scene; 
    } 

    public void openFirstScene(ActionEvent actionEvent) {  
     Stage primaryStage = (Stage)((Node)actionEvent.getSource()).getScene().getWindow(); 
     primaryStage.setScene(firstScene); 
    } 
} 
0

このようにすることができますあまりにも。

public void onBtnClick(ActionEvent event) { 
    try { 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("login.fxml")); 
     Stage stage = (Stage) btn.getScene().getWindow(); 
     Scene scene = new Scene(loader.load()); 
     stage.setScene(scene); 
    }catch (IOException io){ 
     io.printStackTrace(); 
    } 

} 
関連する問題