有没有什么方法可以让我的 JavaFX 代码更加清晰?
Is there any way to create more clarity in my JavaFX code?
我正在学习计算机科学的第一年,我刚刚完成了我的第一个项目,我必须在其中创建一个可以在 SQL 数据库上执行 CRUD 操作的应用程序。此应用程序需要有一个 GUI,为此我们需要使用 JavaFX。
目前我不太确定我处理按钮点击的方式。例如,主屏幕有三个按钮(帐户、个人资料、已观看),每个按钮都将创建一个新场景以及另外三个按钮(创建、编辑、删除)。这导致很多 lambda 表达式相互嵌套,这使得代码看起来非常混乱。下面你会看到我的部分代码:
public class GUI extends Application {
Database db = new Database();
@Override
public void start(Stage stage) throws Exception {
// Three buttons and a Label for the first scene.
Button buttonAccounts = new Button("Accounts");
Button buttonProfiles = new Button("Profiles");
Button buttonWatched = new Button("Watched");
Label pickAnOption = new Label("Pick an option:");
// Two HBoxes, first one for the Label, the other one for the three Buttons.
// Both HBoxes are aligned in the center.
HBox options = new HBox(12);
options.setAlignment(Pos.CENTER);
options.getChildren().addAll(buttonAccounts, buttonProfiles, buttonWatched);
HBox text = new HBox();
text.setAlignment(Pos.CENTER);
text.getChildren().add(pickAnOption);
// The HBoxes are placed in a BorderPane.
// HBox "text" has a top margin of 20 and HBox "options" has a bottom margin of 20.
// This way, the BorderPane will be nicely aligned in the middle of the scene.
BorderPane pane = new BorderPane();
pane.setTop(text);
pane.setMargin(text, new Insets(20, 0, 0 , 0));
pane.setCenter(options);
pane.setMargin(options, new Insets(0, 0, 20, 0));
Scene selectionScreen = new Scene(pane, 500, 100);
stage.setTitle("Netflix Statistix door S. Jaspers, I. Moerenhout en Z. Usmaeva");
stage.setResizable(false);
stage.setScene(selectionScreen);
stage.show();
// EventHandler for the Accounts Button.
buttonAccounts.setOnAction(e -> {
Button buttonCreateAccount = new Button("Create");
Button buttonEditAccount = new Button("Edit");
Button buttonDeleteAccount = new Button("Delete");
Button back = new Button("Back");
Label createEditOrDelete = new Label("Create a new account, or edit/delete an existing account:");
back.setOnAction(e1 -> stage.setScene(selectionScreen));
HBox text1 = new HBox();
text1.setAlignment(Pos.CENTER);
text1.getChildren().add(createEditOrDelete);
HBox options1 = new HBox(12);
options1.setAlignment(Pos.CENTER);
options1.getChildren().addAll(buttonCreateAccount, buttonEditAccount, buttonDeleteAccount);
HBox text2 = new HBox();
text2.setSpacing(50);
text2.getChildren().add(back);
BorderPane pane1 = new BorderPane();
pane1.setTop(text1);
pane1.setMargin(text1, new Insets(15, 0, 0, 0));
pane1.setCenter(options1);
pane1.setMargin(options1, new Insets(0, 0, 15, 0));
pane1.setBottom(text2);
Scene accounts = new Scene(pane1, 500, 100);
stage.setScene(accounts);
// EventHandler for the Create Account button.
buttonCreateAccount.setOnAction(e1 -> {
GridPane grid = new GridPane();
grid.setPadding(new Insets(10, 10, 10, 10));
grid.setVgap(8);
grid.setHgap(10);
Button buttonSave = new Button("Save");
Button buttonCancel = new Button("Cancel");
buttonCancel.setOnAction(e3 -> {
stage.setScene(accounts);
});
Label accountName = new Label("Name:");
Label accountAddress = new Label("Address:");
Label accountCity = new Label("City:");
TextField accountNameInput = new TextField();
TextField accountAddressInput = new TextField();
TextField accountCityInput = new TextField();
grid.add(accountName, 0, 0);
grid.add(accountNameInput, 1, 0);
grid.add(accountAddress, 0, 1);
grid.add(accountAddressInput, 1, 1);
grid.add(accountCity, 0, 2);
grid.add(accountCityInput, 1, 2);
grid.add(buttonSave, 2, 3);
grid.add(buttonCancel, 3, 3);
Scene accountCreation = new Scene(grid);
stage.setScene(accountCreation);
buttonSave.setOnAction(e2 -> {
boolean succeeded = db.createAccount(accountNameInput.getText(), accountAddressInput.getText(), accountCityInput.getText());
if (succeeded) {
new Alert(Alert.AlertType.INFORMATION, "Account successfully created.").show();
} else {
new Alert(Alert.AlertType.WARNING, "Failed to create account.").show();
}
});
});
我对 JavaFX 还是很陌生,我想知道是否有任何方法可以使这段代码更清晰。非常感谢任何建议。
我很想 post 将此作为评论,但我不能。您检查过 FXML 了吗?
它允许您以非常干净和简单的方式设置属性。如果你想要自动完成和检查,那么我推荐 IntelliJ IDEA。这是一篇很好的文章,它解释了 FXML 的好处:https://docs.oracle.com/javafx/2/fxml_get_started/why_use_fxml.htm
- 您可以使
GUI
class 实现 EventHandler 接口。然后你可以在你的代码中写下:
buttonAccounts.setOnAction(this);
handle()
方法的参数包含事件的来源,即被点击的按钮。您的代码如下所示:
public class GUI extends Application implements EventHandler<Action> {
public void handle(ActionEvent e) {
Object source = e.getSource();
if (source == buttonAccounts) {
// Handle it.
}
else if (source == buttonEditAccount) {
}
// etc.
}
}
- 您可以使用 method references。编写一个接受单个
ActionEvent
参数和 returns void
的方法,例如
private void handleButtons(ActionEvent event) {
Object source = event.getSource();
// As above.
}
那你可以写...
buttonAccounts.setOnAction(this::handleButtons);
我正在学习计算机科学的第一年,我刚刚完成了我的第一个项目,我必须在其中创建一个可以在 SQL 数据库上执行 CRUD 操作的应用程序。此应用程序需要有一个 GUI,为此我们需要使用 JavaFX。
目前我不太确定我处理按钮点击的方式。例如,主屏幕有三个按钮(帐户、个人资料、已观看),每个按钮都将创建一个新场景以及另外三个按钮(创建、编辑、删除)。这导致很多 lambda 表达式相互嵌套,这使得代码看起来非常混乱。下面你会看到我的部分代码:
public class GUI extends Application {
Database db = new Database();
@Override
public void start(Stage stage) throws Exception {
// Three buttons and a Label for the first scene.
Button buttonAccounts = new Button("Accounts");
Button buttonProfiles = new Button("Profiles");
Button buttonWatched = new Button("Watched");
Label pickAnOption = new Label("Pick an option:");
// Two HBoxes, first one for the Label, the other one for the three Buttons.
// Both HBoxes are aligned in the center.
HBox options = new HBox(12);
options.setAlignment(Pos.CENTER);
options.getChildren().addAll(buttonAccounts, buttonProfiles, buttonWatched);
HBox text = new HBox();
text.setAlignment(Pos.CENTER);
text.getChildren().add(pickAnOption);
// The HBoxes are placed in a BorderPane.
// HBox "text" has a top margin of 20 and HBox "options" has a bottom margin of 20.
// This way, the BorderPane will be nicely aligned in the middle of the scene.
BorderPane pane = new BorderPane();
pane.setTop(text);
pane.setMargin(text, new Insets(20, 0, 0 , 0));
pane.setCenter(options);
pane.setMargin(options, new Insets(0, 0, 20, 0));
Scene selectionScreen = new Scene(pane, 500, 100);
stage.setTitle("Netflix Statistix door S. Jaspers, I. Moerenhout en Z. Usmaeva");
stage.setResizable(false);
stage.setScene(selectionScreen);
stage.show();
// EventHandler for the Accounts Button.
buttonAccounts.setOnAction(e -> {
Button buttonCreateAccount = new Button("Create");
Button buttonEditAccount = new Button("Edit");
Button buttonDeleteAccount = new Button("Delete");
Button back = new Button("Back");
Label createEditOrDelete = new Label("Create a new account, or edit/delete an existing account:");
back.setOnAction(e1 -> stage.setScene(selectionScreen));
HBox text1 = new HBox();
text1.setAlignment(Pos.CENTER);
text1.getChildren().add(createEditOrDelete);
HBox options1 = new HBox(12);
options1.setAlignment(Pos.CENTER);
options1.getChildren().addAll(buttonCreateAccount, buttonEditAccount, buttonDeleteAccount);
HBox text2 = new HBox();
text2.setSpacing(50);
text2.getChildren().add(back);
BorderPane pane1 = new BorderPane();
pane1.setTop(text1);
pane1.setMargin(text1, new Insets(15, 0, 0, 0));
pane1.setCenter(options1);
pane1.setMargin(options1, new Insets(0, 0, 15, 0));
pane1.setBottom(text2);
Scene accounts = new Scene(pane1, 500, 100);
stage.setScene(accounts);
// EventHandler for the Create Account button.
buttonCreateAccount.setOnAction(e1 -> {
GridPane grid = new GridPane();
grid.setPadding(new Insets(10, 10, 10, 10));
grid.setVgap(8);
grid.setHgap(10);
Button buttonSave = new Button("Save");
Button buttonCancel = new Button("Cancel");
buttonCancel.setOnAction(e3 -> {
stage.setScene(accounts);
});
Label accountName = new Label("Name:");
Label accountAddress = new Label("Address:");
Label accountCity = new Label("City:");
TextField accountNameInput = new TextField();
TextField accountAddressInput = new TextField();
TextField accountCityInput = new TextField();
grid.add(accountName, 0, 0);
grid.add(accountNameInput, 1, 0);
grid.add(accountAddress, 0, 1);
grid.add(accountAddressInput, 1, 1);
grid.add(accountCity, 0, 2);
grid.add(accountCityInput, 1, 2);
grid.add(buttonSave, 2, 3);
grid.add(buttonCancel, 3, 3);
Scene accountCreation = new Scene(grid);
stage.setScene(accountCreation);
buttonSave.setOnAction(e2 -> {
boolean succeeded = db.createAccount(accountNameInput.getText(), accountAddressInput.getText(), accountCityInput.getText());
if (succeeded) {
new Alert(Alert.AlertType.INFORMATION, "Account successfully created.").show();
} else {
new Alert(Alert.AlertType.WARNING, "Failed to create account.").show();
}
});
});
我对 JavaFX 还是很陌生,我想知道是否有任何方法可以使这段代码更清晰。非常感谢任何建议。
我很想 post 将此作为评论,但我不能。您检查过 FXML 了吗? 它允许您以非常干净和简单的方式设置属性。如果你想要自动完成和检查,那么我推荐 IntelliJ IDEA。这是一篇很好的文章,它解释了 FXML 的好处:https://docs.oracle.com/javafx/2/fxml_get_started/why_use_fxml.htm
- 您可以使
GUI
class 实现 EventHandler 接口。然后你可以在你的代码中写下:
buttonAccounts.setOnAction(this);
handle()
方法的参数包含事件的来源,即被点击的按钮。您的代码如下所示:
public class GUI extends Application implements EventHandler<Action> {
public void handle(ActionEvent e) {
Object source = e.getSource();
if (source == buttonAccounts) {
// Handle it.
}
else if (source == buttonEditAccount) {
}
// etc.
}
}
- 您可以使用 method references。编写一个接受单个
ActionEvent
参数和 returnsvoid
的方法,例如
private void handleButtons(ActionEvent event) {
Object source = event.getSource();
// As above.
}
那你可以写...
buttonAccounts.setOnAction(this::handleButtons);