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

Javafx how to create buttons via function?

请帮我让它工作。它冻结而不是改变场景。 以这种方式创建按钮时效果很好:

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;
    }
}

非常感谢您!

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

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

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

当您调用 makeButton 时,您传入当前存储在 s1s2 中的引用 的 值。由于它从未被初始化,它采用默认值 null。由于复制的引用,当您设置 s1s2 时,这不会改变。

你在第一种情况下没有同样的问题,因为你从来没有复制过s1s2。相反,您让 EventHandler 引用 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。这看起来像 tihs:

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 (scenes) 的字段而不是局部变量 (destScene)。