Multiple Components in one column of JavaFX TableView

天大地大妈咪最大 提交于 2019-11-29 11:31:30

Here is a sample for an EditingCell which renders a different control in the cell (TextEdit field or Checkbox) depending on the type of data represented by the Cell's backing field (String or Boolean). Complete executable code is available as a gist.

For your particular example, use the same concept except query the type for either a String => TextField or ObservableList => combobox. Also, for your particular sample, ChoiceBox may be a simpler control to use than ComboBox.

class EditingCell extends TableCell<NamedProperty, Object> {
private TextField textField;
private CheckBox checkBox;
public EditingCell() {}

@Override public void startEdit() {
  if (!isEmpty()) {
    super.startEdit();

    if (getItem() instanceof Boolean) {
      createCheckBox();
      setText(null);
      setGraphic(checkBox);
    } else {
      createTextField();
      setText(null);
      setGraphic(textField);
      textField.selectAll();
    }  
  }
}

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

  if (getItem() instanceof Boolean) {
    setText(getItem().toString());
  } else {
    setText((String) getItem());
  }  
  setGraphic(null);
}

@Override public void updateItem(Object item, boolean empty) {
  super.updateItem(item, empty);

  if (empty) {
    setText(null);
    setGraphic(null);
  } else {
    if (isEditing()) {
      if (getItem() instanceof Boolean) {
        if (checkBox != null) {
          checkBox.setSelected(getBoolean());
        }
        setText(null);
        setGraphic(checkBox);
      } else {
        if (textField != null) {
          textField.setText(getString());
        }
        setText(null);
        setGraphic(textField);
      }  
    } else {
      setText(getString());
      setGraphic(null);
    }
  }
}

private void createTextField() {
  textField = new TextField(getString());
  textField.setMinWidth(this.getWidth() - this.getGraphicTextGap()* 2);
  textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
    @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
      if (!newValue) {
        commitEdit(textField.getText());
      }
    }
  });
}

private void createCheckBox() {
  checkBox = new CheckBox();
  checkBox.setSelected(getBoolean());
  checkBox.setMinWidth(this.getWidth() - this.getGraphicTextGap()* 2);
  checkBox.focusedProperty().addListener(new ChangeListener<Boolean>() {
    @Override public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
      if (!newValue) {
        commitEdit(checkBox.isSelected());
      }
    }
  });
}

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

private Boolean getBoolean() {
  return getItem() == null ? false : (Boolean) getItem();
}
}  

Bellow is the working code for my question. Thank jewelsea

    import javafx.application.Application;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.geometry.Insets;
    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.scene.control.TextField;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.layout.GridPane;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    import javafx.util.Callback;

    public class TableCellWithMultipleComponent extends Application {
        @SuppressWarnings("rawtypes")
        TableColumn answerTypeCol; 
        @SuppressWarnings("rawtypes")
        TableColumn answerCol; 
        ObservableList<String> namesChoiceList;
        @SuppressWarnings("rawtypes")
        ComboBox comboBox;
        TextField textField;

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

        @SuppressWarnings({ "rawtypes", "unchecked" })
        @Override
        public void start(final Stage primaryStage) {
            primaryStage.setTitle("Table Cell With Multiple Components");

             TableView<Person> table = new TableView<Person>();
             table.setEditable(true);
              final ObservableList<Person> data = 
                        FXCollections.observableArrayList(
                            new Person("A", "Multiple Choice"),
                            new Person("JOHN", "Free Text"),
                            new Person("123", "Free Text"),
                            new Person("D", "Multiple Choice")
                        );



            GridPane gridpane = new GridPane();
            gridpane.setPadding(new Insets(5));
            gridpane.setHgap(5);
            gridpane.setVgap(5);


            namesChoiceList = FXCollections.observableArrayList("A", "B", "C", "D", "INVALID_ANSWER", "NO_ANSWER");

            answerCol = new TableColumn();
            answerCol.setText("Answers");
            answerCol.setMinWidth(210);
            answerCol.setEditable(true);
            answerCol.setCellValueFactory(new PropertyValueFactory("answers"));


            answerCol.setCellFactory( new Callback<TableColumn<String, String>, TableCell<String, String>>() {
                @Override
                public TableCell<String, String> call(TableColumn<String, String> arg0) {
                    return new anyMethod();
                }
            });



            answerTypeCol = new TableColumn();
            answerTypeCol.setText("Answers Type");
            answerTypeCol.setMinWidth(210);
            answerTypeCol.setEditable(true);
            answerTypeCol.setCellValueFactory(new PropertyValueFactory("answersType"));



            table.setItems(data);
            table.getColumns().addAll(answerCol, answerTypeCol);

            StackPane root = new StackPane();

            Scene scene =new Scene(root, 500, 550);

            gridpane.add(table, 1, 5,1,20 );


            root.getChildren().addAll(gridpane);
            primaryStage.setScene(scene);
            primaryStage.show();


       }


        private class anyMethod extends TableCell <String, String>{

            @SuppressWarnings({ "unchecked", "rawtypes" })
            public anyMethod(){

                comboBox = new ComboBox();
                textField = new TextField();
                comboBox.setItems(namesChoiceList);
            }

            @Override
            protected void updateItem(String item, boolean empty) {
                super.updateItem(item, empty);
                     if (empty) {
                    setText(null);
                   setGraphic(null);
                    System.out.println("In empty");
                 } else {
                    if( getTableView().getColumns().get(1).getCellData(getIndex()).toString().startsWith("M")){

                     System.out.println("Making ComboBox");
                     setGraphic(comboBox);
                    }
                    else{
                        setGraphic(textField);
                    }
                 }

            }

        }


        public static class Person {
            private final SimpleStringProperty answers;
            private final SimpleStringProperty answersType;


            private Person(String answers, String answersType) {
                this.answers = new SimpleStringProperty(answers);
                this.answersType = new SimpleStringProperty(answersType);
            }

            public String getAnswers() {
                return answers.get();
            }
            public void setAnswers(String answers) {
                this.answers.set(answers);
            }

            public String getAnswersType() {
                return answersType.get();
            }
            public void setAnswersType(String answersType) {
                this.answersType.set(answersType);
            }
        }



    }
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!