2014-02-18 49 views
9

我想在我的TableView中創建一個自定義TableCell。我希望它顯示一個ComboBox,我可以選擇一個String值,然後顯示String值,就像它是一個用戶輸入一樣。這個想法是,用戶不知道哪些是允許的值,所以他可以簡單地在組合框中選擇其中的一個。javafx創建ComboBox TableCell

我想這樣做使我自己的「ComboBoxCell」,但預期它不工作:

public class ComboBoxCell extends TableCell<ClassesProperty, String> { 

    private ComboBox<String> comboBox; 

    public ComboBoxCell() { 
    } 

    @Override 
    public void startEdit() { 
     super.startEdit(); 

     if (comboBox == null) { 
      createComboBox(); 
     } 

     setGraphic(comboBox); 
     setContentDisplay(ContentDisplay.GRAPHIC_ONLY); 
    } 

    @Override 
    public void cancelEdit() { 
     super.cancelEdit(); 

     setText(String.valueOf(getItem())); 
     setContentDisplay(ContentDisplay.TEXT_ONLY); 
    } 

    public void updateItem(String item, boolean empty) { 
     super.updateItem(item, empty); 

     if (empty) { 
      setText(null); 
      setGraphic(null); 
     } else { 
      if (isEditing()) { 
       if (comboBox != null) { 
        comboBox.setValue(getString()); 
       } 
       setGraphic(comboBox); 
       setContentDisplay(ContentDisplay.GRAPHIC_ONLY); 
      } else { 
       setText(getString()); 
       setContentDisplay(ContentDisplay.TEXT_ONLY); 
      } 
     } 
    } 

    private void createComboBox() { 
     // ClassesController.getLevelChoice() is the observable list of String 
     comboBox = new ComboBox<>(ClassesController.getLevelChoice()); 
     comboBox.setMinWidth(this.getWidth() - this.getGraphicTextGap()*2); 
     comboBox.setOnKeyPressed(new EventHandler<KeyEvent>() { 
      @Override 
      public void handle(KeyEvent t) { 
       if (t.getCode() == KeyCode.ENTER) { 
        commitEdit(comboBox.getSelectionModel().getSelectedItem()); 
       } else if (t.getCode() == KeyCode.ESCAPE) { 
        cancelEdit(); 
       } 
      } 
     }); 
    } 

    private String getString() { 
     return getItem() == null ? "" : getItem().toString(); 
    } 
} 

然後在我的「主」的應用程序:

levelChoice = FXCollections.observableArrayList(
     new String("Bla"), 
     new String("Blo") 
    ); 

// Level Column : String value 
Callback<TableColumn, TableCell> comboBoxFactory = new Callback<TableColumn, TableCell>() { 
     @Override 
     public TableCell call(TableColumn p) { 
      return new ComboBoxCell(); 
     } 
    }; 

levelColumn.setCellValueFactory(
     new PropertyValueFactory<ClassesProperty, String>("level") 
    ); 
levelColumn.setCellFactory(comboBoxFactory); 

任何想法? 謝謝!

回答

16

我發現瞭解決方案:

levelChoice = FXCollections.observableArrayList("Bla", "Blo"); 

levelColumn.setCellValueFactory(
    new PropertyValueFactory<ClassesProperty, String>("level") 
); 
levelColumn.setCellFactory(ComboBoxTableCell.forTableColumn(levelChoice)); 
levelColumn.setOnEditCommit(
    new EventHandler<CellEditEvent<ClassesProperty, String>>() { 
     @Override 
     public void handle(CellEditEvent<ClassesProperty, String> t) { 
      ((ClassesProperty) t.getTableView().getItems().get(t.getTablePosition().getRow())).setLevel(t.getNewValue()); 
     }; 
    } 
); 
+2

在'''handle'''線也可以是:'''t.getRowValue()setLevel(t.getNewValue());' ''這可以避免演員陣容。 –