Javafx如何通过函数创建按钮?

时间:2016-04-08 20:34:24

标签: java button javafx scene

请帮我搞定。它冻结而不是改变场景。 按钮以这种方式创建时,它可以正常工作:

Button b1 = new Button("Go to s2");
b1.setOnAction(e -> window.setScene(s2));
Button b2 = new Button("Go to s1");
b2.setOnAction(e -> window.setScene(s1));

但我想让它更优雅......

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.stage.Stage;

public class Main extends Application {

    Stage window;
    Scene s1,s2;

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        window = primaryStage;

        Button b1 = makeButton("Go to s2", s2);
        Button b2 = makeButton("Go to s1", s1);

        s1 = new Scene(b1);
        s2 = new Scene(b2);

        primaryStage.setScene(s1);
        primaryStage.show();
    }

    public Button makeButton(String name, Scene destScene)  {
        Button button = new Button(name);
        button.setOnAction(e -> window.setScene(destScene));
        return button;
    }
}

非常感谢你!

1 个答案:

答案 0 :(得分:1)

查看所有内容的初始化顺序:

makeButton

当您致电s1时,您会传递当前存储在s2null中的参考的值。由于它从未初始化,因此默认值为s1。由于复制的引用而设置s2s1时,这不会更改。

在第一种情况下,您没有遇到同样的问题,因为您从不复制s2EventHandler。相反,您有Main引用当前Button b1 = new Button("Go to s2"); b1.setOnAction(e -> window.setScene(this.s2)); 实例中的字段,一旦设置它就会正确更新。因此,您的原始代码与此相当:

Main

所以你要复制对封闭的makeButton(String, EventHandler<ActionEvent>)实例的引用,而不是对按钮本身的引用。

遗憾的是,我没有看到任何微不足道的修复。我看到的最简单的解决方案是将您的功能更改为Button b1 = makeButton("Go to s2", e -> window.setScene(s2)); ,并将其命名为:

Button

不如你想要的那么好,但它应该有效。

另一种可能的解决方案是将所有makeButton放入一个数组中,然后将索引传递到该数组public class Main extends Application { Stage window; Scene[] scenes = new Scene[2]; @Override public void start(Stage primaryStage) throws Exception { window = primaryStage; Button b1 = makeButton("Go to s2", 1); Button b2 = makeButton("Go to s1", 0); scenes[0] = new Scene(b1); scenes[1] = new Scene(b2); primaryStage.setScene(scenes[0]); primaryStage.show(); } public Button makeButton(String name, int destScene) { Button button = new Button(name); button.setOnAction(e -> window.setScene(scenes[destScene])); return button; } } 。这看起来像是:

EventHandler

这会更改Main以引用scenesdestScene)字段而非局部变量(if (!IsPostBack) { } )。