2016-11-24 17 views
0

Ich würde gerne einen Handler zum ComboBox innerhalb eines ComboBoxTableCell in einem TableView in JavaFX8 hinzufügen. Ich kann sehen, dass es einen privaten ComboBox Wert in der ComboBoxTableCell Klasse gibt, aber ich habe keine Ahnung, wie man darauf zugreifen kann. Ich erkläre der Spalte, eine ComboBoxTableCell über die setCellFactory Methode zu verwenden. Gibt es eine Möglichkeit, die ComboBox zu bekommen?JavaFX: get ComboBox von ComboBoxTableCell

BEARBEITEN: Ich möchte einen Listener zum ComboBox hinzufügen, der die Auswahl von Elementen durch Eingabe von Schlüsseln ermöglicht. Ich habe bereits eine für eine normale ComboBox und ich möchte sie für die ComboBox in der TableCell wiederverwenden.

+2

Warum möchten Sie auf die 'ComboBox' zugreifen. Es gibt wahrscheinlich einen besseren Weg, dies zu tun ... – fabian

+0

aktualisiert die Beschreibung – YellowSub

Antwort

1

Nach meinem Wissen gibt es keine Möglichkeit, den Verweis auf die ComboBox der ComboBoxTableCell zu bekommen. Wenn das stimmt, ist es nicht möglich, einen Listener hinzuzufügen.

Ein alternativer Ansatz besteht darin, eine eigene benutzerdefinierte Zelle zu erstellen, die eine ComboBox enthält. Mit diesem Ansatz können Sie die ComboBox beliebig manipulieren.

import java.util.function.BiConsumer; 
import java.util.function.Function; 

import javafx.application.Application; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.value.ObservableValue; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.scene.Scene; 
import javafx.scene.control.ComboBox; 
import javafx.scene.control.TableCell; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.stage.Stage; 

public class ComboBoxTable extends Application { 
    @Override 
    public void start(Stage stage) { 
     int numOfCols = 2; 

     ObservableList<ObservableList<String>> tableData = FXCollections.observableArrayList(); 

     // Generate dummy data. 
     for (int i = 0; i < 10; i++) { 
      ObservableList<String> row = FXCollections.observableArrayList(); 

      for (int j = 0; j < numOfCols; j++) 
       row.add("Row" + i + "Col" + j); 

      tableData.add(row); 
     } 

     TableView<ObservableList<String>> table = new TableView<ObservableList<String>>(); 

     // Add columns to the table. 
     for (int i = 0; i < numOfCols; i++) { 
      final int j = i; 
      // The fourth argument in the method, the BiConsumer, might require 
      // an explanation. Basically we are saying that when the BiConsumer 
      // are given an ObservableList<String> and a String, we set the 
      // value of the String as the value of the element at position "j" 
      // of the row, where "j" will be the column index. 
      table.getColumns().add(addComboBoxColumn(i, "Column " + i, row -> new SimpleStringProperty(row.get(j)), 
        (row, newText) -> row.set(j, newText))); 
     } 

     table.getItems().addAll(tableData); 

     Scene scene = new Scene(table); 

     stage.setScene(scene); 
     stage.show(); 
    } 

    /** 
    * Returns a TableColumn with ComboBoxCells. 
    */ 
    private TableColumn<ObservableList<String>, String> addComboBoxColumn(int index, String name, 
      Function<ObservableList<String>, ObservableValue<String>> property, 
      BiConsumer<ObservableList<String>, String> updater) { 

     TableColumn<ObservableList<String>, String> col = new TableColumn<ObservableList<String>, String>(name); 

     col.setCellValueFactory(cellData -> property.apply(cellData.getValue())); 

     col.setCellFactory(e -> new ComboBoxCell(updater, index)); 

     return col; 
    } 

    /** 
    * A TableCell with a ComboBox in it. 
    */ 
    public class ComboBoxCell extends TableCell<ObservableList<String>, String> { 
     private ComboBox<String> comboBox = new ComboBox<String>(); 

     /** 
     * @param updater 
     *   The updater makes sure that the cell value corresponds 
     *   with the value in the ComboBox. 
     * @param colIndex 
     *   The index of this column. 
     */ 
     public ComboBoxCell(BiConsumer<ObservableList<String>, String> updater, int colIndex) { 
      comboBox.setEditable(true); 

      comboBox.getEditor().textProperty().addListener((old, oldValue, newValue) -> { 
       if (getIndex() >= 0) { 
        // We provide the BiConsumer.accept() with an 
        // ObservableList<String> and a String. The BiConsumer will 
        // do the operation specified in the definition we provided 
        // in addColumn() using these two objects. 
        updater.accept(getTableView().getItems().get(getIndex()), (String) newValue); 
       } 
      }); 
     } 

     @Override 
     protected void updateItem(String item, boolean empty) { 
      super.updateItem(item, empty); 
      if (empty) { 
       setGraphic(null); 
      } else { 
       // If we don't check if this value is the same as the old one, 
       // the cursor is moved to the beginning of the editor every time 
       // anything is typed. 
       if (!item.equals(comboBox.getEditor().getText())) { 
        comboBox.getEditor().setText(item); 
       } 
       setGraphic(comboBox); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     launch(); 
    } 
}