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
时,您传入当前存储在 s1
和 s2
中的引用 的 值。由于它从未被初始化,它采用默认值 null
。由于复制的引用,当您设置 s1
和 s2
时,这不会改变。
你在第一种情况下没有同样的问题,因为你从来没有复制过s1
和s2
。相反,您让 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
)。
请帮我让它工作。它冻结而不是改变场景。 以这种方式创建按钮时效果很好:
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
时,您传入当前存储在 s1
和 s2
中的引用 的 值。由于它从未被初始化,它采用默认值 null
。由于复制的引用,当您设置 s1
和 s2
时,这不会改变。
你在第一种情况下没有同样的问题,因为你从来没有复制过s1
和s2
。相反,您让 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
)。