TableView,设置可编辑的单元格

TableView,设置可编辑的单元格

问题描述:

我尝试使表单元格可编辑。我设法用两个具有String值的Collumns来做到这一点,但是我不能用表示Integer值的列做这个。TableView,设置可编辑的单元格

地方与X就是编译得到的错误:

The method setCellFactory(Callback<TableColumn<DataModel,Integer>,TableCell<DataModel,Integer>>) in the type TableColumn<DataModel,Integer> is not applicable for the arguments (Callback<TableColumn<DataModel,String>,TableCell<DataModel,String>>) 

与XX地方就是编译得到的错误:

The method setOnEditCommit(EventHandler<TableColumn.CellEditEvent<DataModel,Integer>>) in the type TableColumn<DataModel,Integer> is not applicable for the arguments ((CellEditEvent<DataModel, Integer> event) -> {}) 

继承人的代码:

public void initialize(URL location, ResourceBundle resources) { 
    //Tworzymy sobie kolumny, które będą odpowiadać oraz przyjmować konretne dane 
    TableColumn<DataModel, String> nameColumn = new TableColumn<DataModel, String>("Name"); 
    nameColumn.setMinWidth(100); 
    TableColumn<DataModel, String> surnameColumn = new TableColumn<DataModel, String>("Surname"); 
    surnameColumn.setMinWidth(100); 
    TableColumn<DataModel, Integer> ageColumn = new TableColumn<DataModel, Integer>("Age"); 
    ageColumn.setMinWidth(100); 
    TableColumn<DataModel, Integer> telNumberColumn = new TableColumn<DataModel, Integer>("Tel. Number"); 
    telNumberColumn.setMinWidth(100); 

    //dodajemy kolumny do okna 
    tableView.getColumns().addAll(nameColumn,surnameColumn,ageColumn,telNumberColumn); 

    //podajemy nazwy zmiennych, których wartości mają się wyświetlać w poszczególnych kolumnach 
    nameColumn.setCellValueFactory(new PropertyValueFactory<>("sName")); 
    surnameColumn.setCellValueFactory(new PropertyValueFactory<>("sSurname")); 
    ageColumn.setCellValueFactory(new PropertyValueFactory<>("iAge")); 
    telNumberColumn.setCellValueFactory(new PropertyValueFactory<>("iPhoneNumber")); 

    //Sprawiamy że poszczególne kolumny stają się edytowalne 
    nameColumn.setCellFactory(TextFieldTableCell.<DataModel>forTableColumn()); 
    nameColumn.setOnEditCommit((CellEditEvent<DataModel, String> event) -> { 
     ((DataModel) event.getTableView().getItems(). get(event.getTablePosition().getRow())). setsName(event.getNewValue()); 
    }); 
    surnameColumn.setCellFactory(TextFieldTableCell.<DataModel>forTableColumn()); 
    surnameColumn.setOnEditCommit((CellEditEvent<DataModel, String> event) -> { 
     ((DataModel) event.getTableView().getItems(). get(event.getTablePosition().getRow())). setsSurname(event.getNewValue()); 
    }); 
X ageColumn.setCellFactory(TextFieldTableCell.<DataModel>forTableColumn()); 
XX ageColumn.setOnEditCommit((CellEditEvent<DataModel, Integer> event) -> { 
    // ((DataModel) event.getTableView().getItems(). get(event.getTablePosition().getRow())). setiAge(Integer.valueOf(event.getNewValue())); 

    }); 
X telNumberColumn.setCellFactory(TextFieldTableCell.<DataModel>forTableColumn()); 
XX telNumberColumn.setOnEditCommit((CellEditEvent<DataModel, Integer> event) -> { 
//   ((DataModel) event.getTableView().getItems(). get(event.getTablePosition().getRow())). setiPhoneNumber(Integer.valueOf(event.getNewValue())); 

    }); 

    tableView.setPlaceholder(new Label("Pust tabelka!"));//jaki element dodać jeśli tabelka nie jest wyświetlona 
    tableView.setEditable(true); 

    tableView.setItems(dataList); //wczytujemy dane do przygotowanej tabelki 

    buttAdd.setOnAction((ActionEvent e) -> { 
     buttAddAction(e); 
    }); 
} 

我采取Oracle TableView教程,它相当困难。帮帮我。

+0

,什么是错误?堆栈跟踪? – eckig 2015-02-01 10:02:40

+0

请参阅开始时的说明。它是一个编译器错误。我无法运行该程序。 – Tomasz 2015-02-01 10:58:31

+0

哎呀我没有看到第一眼看到这一行,我的坏.. – eckig 2015-02-01 11:54:05

问题是TextFieldTableCell.forTableColumn()被键入字符串值。看到默认的实现:

public static <S> Callback<TableColumn<S,String>, TableCell<S,String>> forTableColumn() { 
    return forTableColumn(new DefaultStringConverter()); 
} 

你需要的是TextFieldTableCellIntegerStringConverter,例如:

ageColumn.setCellFactory(TextFieldTableCell.<DataModel, Integer>forTableColumn(new IntegerStringConverter())); 
+0

我尝试了自定义单元格编辑事件,如Oracle教程中所示,并且它的String属性不起作用,并且不适用于SimpleIntegerValues。再次出现类型问题。那么,最好是保留数据类中的每个变量(例如我的DataModel)SimpleStringProperty以避免像那样的转换? – Tomasz 2015-02-01 13:01:52

+0

如果您还有其他问题,请在此处作为新主题询问他们,但评论部分不是正确的地方;-) – eckig 2015-02-01 13:09:23

+0

@eckig - 您拯救了我的生命:) – 2016-12-27 15:17:52

我搜索过很多答案,我已经借/扩展/合并本解。焦点从编辑的单元格移动时编辑提交。我有一个可以在表中表示的每种数据类型的公共类:EditingTextCell,EditingIntegerCell等。这些公共类可以应用于任何表,只要数据表示为访问要显示的数据的类的可观察列表作为属性。我发布这个解决方案是因为我面临为应用程序中的每个表的每列创建一个类。目前,双值和组合框版本与特定表格的特定列绑定。随着时间的推移,我会做一个通用的版本。请原谅我不提交源代码链接 - 我忘了书签他们,因为我仔细阅读他们。

Java文档表明即将推出更简单的方法。

实施例的使用对于整数字段:

TableColumn<Factor, Number> noLevelsCol = 
      new TableColumn<>("No. Levels"); 
    noLevelsCol.setCellValueFactory(
      new PropertyValueFactory("numberLevels")); 
    noLevelsCol.setMinWidth(40); 
    noLevelsCol.setCellFactory(col -> new EditingIntegerCell<>()); 
    noLevelsCol.setOnEditCommit((CellEditEvent<Factor, Number> t) -> { 
     ((Factor) t.getTableView().getItems().get(
       t.getTablePosition().getRow()) 
       ).setNumberLevels(t.getNewValue().intValue()); 
    }); 

实施例的使用用于字符串字段:

TableColumn<Factor, String> nameCol = new TableColumn<>("Name"); 
    nameCol.setMinWidth(60); 
    nameCol.setCellValueFactory(
      new PropertyValueFactory("factorName")); 
    nameCol.setCellFactory(cellFactory); 
    nameCol.setOnEditCommit((CellEditEvent<Factor, String> t) -> { 
     ((Factor) t.getTableView().getItems().get(
       t.getTablePosition().getRow()) 
       ).setFactorName(t.getNewValue()); 
    }); 

因子类的定义: 公共类因子{

private final IntegerProperty factorID = new SimpleIntegerProperty(); 
public IntegerProperty getFactorID() {  return factorID; } 

private StringProperty factorName = new SimpleStringProperty(); 
public void setFactorName(String value) { 
      factorNameProperty().set(value); } 
public String getFactorName() { return factorNameProperty().get(); } 
public StringProperty factorNameProperty() { 
    if (factorName == null) factorName = 
     new SimpleStringProperty(this, "factorName"); 
    return factorName; 
} 

private IntegerProperty numberLevels = new SimpleIntegerProperty(); 
public void setNumberLevels(int value) { 
     numberLevelsProperty().set(value); } 
public IntegerProperty getNumberLevels() { return numberLevels; } 
public IntegerProperty numberLevelsProperty() { 
    if (numberLevels == null) numberLevels = 
      new SimpleIntegerProperty(this, "numberLevels"); 
    return numberLevels; 
} 

private StringProperty listOfLevels = new SimpleStringProperty(); 
public void setListOfLevels(String value) { 
     listOfLevelsProperty().set(value); } 
public String getListOfLevels() { return listOfLevelsProperty().get(); } 
public StringProperty listOfLevelsProperty() { 
    if (listOfLevels == null) listOfLevels = 
      new SimpleStringProperty(this, "listOfLevels"); 
    return listOfLevels; 
} 


// Constructors 
public Factor(int factorID, String factorName) { 
    this.factorID.set(factorID); 
    this.factorName.set(factorName); 
    this.numberLevels.set(1); 
    this.listOfLevels.set("-1, 1"); 
} 

public Factor(int factorID, String factorName, int numberLevels, 
       String listOfLevels) { 
    this.factorID.set(factorID); 
    this.factorName.set(factorName); 
    this.numberLevels.set(numberLevels); 
    this.listOfLevels.set(listOfLevels); 
} 

@Override 
public String toString() { 
    return "Factor{" + "factorName=" + factorName + '}'; 
} 

public String[] getLevels() { 
    return listOfLevels.getValue().split(","); 
} 

}

数据加载到表 最终ObservableList factorList = FXCollections。observableArrayList( )新因子(1,“Factor1”,2,“-1,1”) );

factorTableView.setEditable(true); 
    factorTableView.getColumns().clear(); 
    factorTableView.setItems(factorList); 
    boolean addAll; 
    addAll = factorTableView.getColumns().addAll(idCol, 
        nameCol, noLevelsCol, levelsCol); 

的EditingIntegerCell类 公共类EditingIntegerCell扩展的TableCell {

private TextField textField; 
    private final Pattern intPattern = Pattern.compile("-?\\d+"); 

    public EditingIntegerCell() { 
    } 

    @Override 
    public void startEdit() { 
     if (!isEmpty()) { 
      super.startEdit(); 
      createTextField(); 
      setText(null); 
      setGraphic(textField); 
      textField.selectAll(); 
     } 
    } 

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

     setText((String) getItem().toString()); 
     setGraphic(null); 
    } 

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

     if (empty) { 
      setText(null); 
      setGraphic(null); 
     } else { 
      if (isEditing()) { 
       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(
      (ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) 
         -> { 
      if (!arg2) { 
       processEdit(); 
      } 
     }); 
    } 

    private void processEdit() { 
     String text = textField.getText(); 
     if (intPattern.matcher(text).matches()) { 
      commitEdit(Integer.parseInt(text)); 
     } else { 
      cancelEdit(); 
     } 
    } 

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

**的EditingTextCell类** 公共类EditingTextCell扩展的TableCell {

private TextField textField; 

    public EditingTextCell() { 
    } 

    @Override 
    public void startEdit() { 
     if (!isEmpty()) { 
      super.startEdit(); 
      createTextField(); 
      setText(null); 
      setGraphic(textField); 
      textField.selectAll(); 
     } 
    } 

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

     setText((String) getItem()); 
     setGraphic(null); 
    } 

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

     if (empty) { 
      setText(null); 
      setGraphic(null); 
     } else { 
      if (isEditing()) { 
       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(
      (ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) 
         -> { 
      if (!arg2) { 
       commitEdit(textField.getText()); 
      } 
     }); 
    } 

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