我开始使用Java和JavaFX,对于我的第一个项目,我需要2个下拉框,A和B.当我从A中选择一个项目时,B中的内容会自动更改。我已经设法使用setOnAction,但我想知道是否有更好的方法来做到这一点。听众可能吗?我已经看了一下,但我不完全确定如何使用它们。
到目前为止,这是我的代码:
@Override
public void start(Stage primaryStage) {
String[] mainlist = {"Selector A", "Selector B"};
String[] options1 = {"Option 1", "Option 2", "Option 3"};
String[] options2 = {"Option 4", "Option 5", "Option 6"};
primaryStage.setTitle("UI Test");
Group root = new Group();
Scene scene = new Scene(root, 450, 450, Color.WHITE);
TabPane tabPane = new TabPane();
BorderPane mainPane = new BorderPane();
mainPane.setCenter(tabPane);
mainPane.prefHeightProperty().bind(scene.heightProperty());
mainPane.prefWidthProperty().bind(scene.widthProperty());
//Create Tab 1
Tab tab1 = new Tab();
tab1.setText("TestTab");
tab1.setClosable(false);
//Create grid1 and add it to Tab 1
GridPane grid1 = new GridPane();
grid1.setAlignment(Pos.BASELINE_LEFT);
grid1.setHgap(5);
grid1.setVgap(5);
grid1.setPadding(new Insets(10, 10, 10, 10));
grid1.getColumnConstraints().add(new ColumnConstraints(100));
grid1.getColumnConstraints().add(new ColumnConstraints(300));
tab1.setContent(grid1);
tabPane.getTabs().add(tab1);
//Add combobox1 to grid1
grid1.add(new Label("Action:"), 0, 1); //Places label
ObservableList<String> aComboList = FXCollections.observableArrayList();
for (int i = 0; i < mainlist.length; i++){
aComboList.add(mainlist[i]);
}
ComboBox<String> aBoxProjects = new ComboBox<String>(aComboList);
grid1.add(aBoxProjects, 1, 1);
//Add combobox2 to grid1
grid1.add(new Label("Elements:"), 0, 2); //Places label
ObservableList<String> bComboList = FXCollections.observableArrayList();
ComboBox<String> bBoxProjects = new ComboBox<String>(bComboList);
grid1.add(bBoxProjects, 1, 2);
root.getChildren().add(mainPane);
primaryStage.setScene(scene);
primaryStage.show();
aBoxProjects.setOnAction (new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent b) {
bComboList.clear();
if (aBoxProjects.getValue().toString() == mainlist[0]){
for (int i = 0; i < options1.length; i++){
bComboList.add(options1[i]);
}
} else {
for (int i = 0; i < options2.length; i++){
bComboList.add(options2[i]);
}
}
}
});
}
这只是一种初步方法。随着时间的推移,数组将被从文件读取的字符串等替换。现在我更关心正确使用JavaFX。有没有办法以更优雅的方式编写相同的代码?
谢谢!
答案 0 :(得分:0)
您可以减少所拥有的代码量,并且仍然使用相同的基本策略:
ObservableList<String> aComboList = FXCollections.observableArrayList(mainlist);
ComboBox<String> aBoxProjects = new ComboBox<String>(aComboList);
grid1.add(aBoxProjects, 1, 1);
//Add combobox2 to grid1
grid1.add(new Label("Elements:"), 0, 2); //Places label
ObservableList<String> bComboList = FXCollections.observableArrayList();
ComboBox<String> bBoxProjects = new ComboBox<String>(bComboList);
grid1.add(bBoxProjects, 1, 2);
root.getChildren().add(mainPane);
primaryStage.setScene(scene);
primaryStage.show();
aBoxProjects.setOnAction (new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent b) {
if (aBoxProjects.getValue().toString() == mainlist[0]){
bcomboList.setAll(options1);
} else {
bcomboList.setAll(options2);
}
}
});
你可以使用lambda表达式代替匿名内部类:
aBoxProjects.setOnAction (b -> {
if (aBoxProjects.getValue() == mainlist[0]){
bcomboList.setAll(options1);
} else {
bcomboList.setAll(options2);
}
});
甚至
aBoxProjects.setOnAction(b ->
bcomboList.setAll(aBoxProjects.getValue() == mainlist[0] ? options1 : options2));
您也可以使用绑定而不是使用事件处理程序:
ObservableList<String> aComboList = FXCollections.observableArrayList(mainlist);
ComboBox<String> aBoxProjects = new ComboBox<String>(aComboList);
grid1.add(aBoxProjects, 1, 1);
//Add combobox2 to grid1
grid1.add(new Label("Elements:"), 0, 2); //Places label
ObservableList<String> bComboList1 = FXCollections.observableArrayList(options1);
ObservableList<String> bComboList2 = FXCollections.observableArrayList(options2);
ComboBox<String> bBoxProjects = new ComboBox<String>();
grid1.add(bBoxProjects, 1, 2);
bBoxProjects.itemsProperty().bind(Bindings.createObjectBinding(() -> {
if (aBoxProject.getValue() == mainlist[0]) {
return bComboList1 ;
} else if (aBoxProject.getValue() == mainlist[1]) {
return bComboList2 ;
} else { // no selection
return FXCollections.emptyObservableList();
}
}, aBoxProject.valueProperty()));
root.getChildren().add(mainPane);
primaryStage.setScene(scene);
primaryStage.show();