【问题标题】:Multiple Components in one column of JavaFX TableViewJavaFX TableView 一列中的多个组件
【发布时间】:2012-12-13 05:36:50
【问题描述】:

我正在使用 JavaFx 2.2。我有一个问题,我无法在 TableView 列中放置不同的组件。例如我有两列

1) 回答

2) 答案类型

如果 AnswerType 包含“Multiple Choice”,则 Answer Column 中的相应单元格应显示 ComboBox,否则应显示 TextField。

我在下面有一个代码示例,但它显示 ComboBox 或 TextField 但不是同时显示在同一列的不同单元格中。

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.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.scene.control.cell.ComboBoxTableCell;

public class TableCellWithMultipleComponent extends Application {

     @SuppressWarnings("rawtypes")
TableColumn answerTypeCol; 
@SuppressWarnings("rawtypes")
TableColumn answerCol; 
ObservableList<String> namesChoiceList;

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")
    @Override
    protected void updateItem(String item, boolean arg1) {
        super.updateItem(item, arg1);

        answerCol.setCellFactory(ComboBoxTableCell.<String, String>forTableColumn(namesChoiceList));

        /****  I have to execute this commented code so that if the column cell has text "Multiple Choice" then
         * it displays the comboBox otherwise it displays the text field in the Table View cell

        if (item.equalsIgnoreCase("Multiple Choice")){
            answerCol.setCellFactory(ComboBoxTableCell.<String, String>forTableColumn(namesChoiceList));
        }
        else{
            //answerCol.setCellFactory(TextFieldTableCell.<String>forTableColumn());
        }
    ****/
    }

}


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



}

【问题讨论】:

  • 您想在相应的表格单元格中显示combo boxtext field??
  • 两者都取决于答案类型列

标签: tableview javafx-2 javafx tablecell tablecolumn


【解决方案1】:

这是一个 EditingCell 示例,它根据单元格的支持字段(字符串或布尔值)表示的数据类型在单元格(文本编辑字段或复选框)中呈现不同的控件。 Complete executable code is available as a gist.

对于您的特定示例,使用相同的概念,但查询 String => TextField 或 ObservableList => 组合框的类型。此外,对于您的特定示例,ChoiceBox 可能比 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();
}
}  

【讨论】:

    【解决方案2】:

    波纹管是我的问题的工作代码。感谢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);
                }
            }
    
    
    
        }
    

    【讨论】:

      猜你喜欢
      • 2014-08-06
      • 2020-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 2015-01-31
      • 1970-01-01
      • 2016-04-12
      相关资源
      最近更新 更多