我不了解在JavaFX和SceneBuilder中切换场景的代码

时间:2015-08-20 22:05:09

标签: javafx scenebuilder

进行一些谷歌搜索,我想通过将此方法分配给按钮,我可以在同一阶段改变场景:

Parent root = FXMLLoader.load(getClass().getResource("view/bambam"));
Stage stage= (Stage) ((Node) event.getSource()).getScene().getWindow();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();

我不明白第二行。括号中的阶段和节点是什么意思?是某种类型的铸造?它是指"主要"不知怎的?如果有人能够完全解释这句话或者告诉我我错过了哪些材料,我将非常感激。

1 个答案:

答案 0 :(得分:2)

在表达式前面的括号中放置类型的语法是向下转换,可以很好地解释herehere。如果您扩展代码,可能会更清楚:

Parent root = FXMLLoader.load(getClass().getResource("view/bambam"));

// get the source of the event
Object eventSource = event.getSource(); 

// the event only knows its source is some kind of object, however, we
// registered this listener with a button, which is a Node, so we know
// the actual runtime type of the source must be Button (which is a Node)
// So tell the compiler we are confident we can treat this as a Node:

Node sourceAsNode = (Node) eventSource ;

// get the scene containing the Node (i.e. containing the button):
Scene oldScene = sourceAsNode.getScene();

// get the window containing the scene:
Window window = oldScene.getWindow();

// Again, the Scene only knows it is in a Window, but we know we specifically
// put it in a stage. So we can downcast the Window to a Stage:

Stage stage = (Stage) window ;

// Equivalently, just omitting all the intermediate variables:
// Stage stage= (Stage) ((Node) event.getSource()).getScene().getWindow();

Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();

恕我直言,这是非常糟糕的代码。首先,向下转向在某种程度上回避了通常的编译时类型检查,依赖于我们对编码逻辑的分析以避免运行时异常。因此,在可能的情况下避免使用它是一种好习惯。

在这种情况下,您声明此代码是使用按钮注册的处理程序的一部分。因此,事件的来源是按钮。因此,我们可以只使用现有的引用,而不是通过所有这些步骤来获取对按钮的引用。换句话说,你有类似的东西:

button.setOnAction(event -> {

    Parent root = FXMLLoader.load(getClass().getResource("view/bambam"));
    Stage stage= (Stage) ((Node) event.getSource()).getScene().getWindow();
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();

});

此处((Node) event.getSource()) 必须button,因此您可以立即简化为

button.setOnAction(event -> {
    Parent root = FXMLLoader.load(getClass().getResource("view/bambam"));
    Stage stage = (Stage) button.getScene().getWindow();
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();
});

其次,根本不需要替换Scene:为什么不替换现有root的{​​{1}}?为此你可以做到

Scene

(显然button.setOnAction(event -> { Parent root = FXMLLoader.load(getClass().getResource("view/bambam")); Scene scene = button.getScene(); scene.setRoot(root); }); 已经显示,因为用户点击了按钮,因此Stage是多余的。)

如果您愿意,可以将其简化为

stage.show()

甚至只是

button.setOnAction(event -> {
    Parent root = FXMLLoader.load(getClass().getResource("view/bambam"));
    button.getScene().setRoot(root);
});