2017-08-30 8 views
0

私はJavaとJavaFXを使い始めています。最初のプロジェクトでは、AとBの2つのドロップダウンボックスが必要です。Aから項目を選択すると、Bの内容が自動的に変更されます。私はsetOnActionを使ってそれを行うことができましたが、もっと良い方法があるのだろうかと思います。リスナーはおそらく?私はそれをちょっと見たことがありますが、私はそれらをどのように使用するか完全にはわかりません。JavaFXで2つの相互依存ドロップダウンボックスを作成する正しい方法はありますか?

これは、これまでの私のコードです:

@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

あなたが持っているコードの量を削減し、まだ同じ基本的な戦略を使用することができます

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

    } 
}); 

をし、あなたの代わりに匿名内部クラスのイベントハンドラのためのラムダ式を使用することができます。

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(); 
+1

注ラムダは、あなたはJavaは8 –

+0

恐ろしい使用している場合にのみ使用可能です、ありがとう包括的な応答のためにたくさん。あなたはラムダ式やバインディングを含めて、私にはかなり読み物を与えてくれました:) – hmdrummer

関連する問題