JavaFX Tableview不绑定/还原 [英] JavaFX Tableview not binding/reverting

查看:46
本文介绍了JavaFX Tableview不绑定/还原的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在诊断行为方面寻求帮助,因为我对可能发生的情况不知所措.

Looking for help in diagnosing a behavior, as I'm at a loss for where it may be occurring.

在表编辑中,标签会更新,但值似乎从未更改过,因为每当更新表时,值都会还原.这种情况发生在排序过程中,可以通过以下方式证明它是正确的:

On table edit, the labels update, but the values don't ever seem to, as whenever the table is updated the values revert. This happens with sorting, and can be shown to be true via:

for(Row r : elementsTable.getItems().get(0))
   System.out.println(r.getSymbol() + r.getWeight() + r.getAtom());

GUI:

@FXML
private TextField row1;
@FXML
private TextField row2;
@FXML
private TextField row3;
@FXML
private TableView<Row> elementsTable;
private List<Row> row;
private ObservableList<Row> oRow;

@Override
public void initialize(URL url, ResourceBundle rb) {
    // TODO
    row = new ArrayList();
}  

private void addRow(ActionEvent event) {    
 elementsTable.getItems().add(new Row(
         row1.getText(),
         row2.getText(),
         row3.getText()));
}

public void
construct(List<String> z, List<String> w, List<String> z)
throws Exception{
    //populate table rows
    for(int i = 0; i < z.size(); i++){
        row.add(new Row(z.get(i), w.get(i), a.get(i)));
    }
    oRow = FXCollections.observableArrayList(row);
    elementsTable.setItems(oRow);

}

FXML

  <TableView fx:id="elementsTable" editable="true" layoutX="67.0" layoutY="124.0" prefHeight="237.0" prefWidth="523.0">
     <columns>
        <TableColumn fx:id="elementCol" editable="true" prefWidth="138.0" text="Element">
           <cellFactory>
              <TextFieldTableCell fx:factory="forTableColumn" />
           </cellFactory>
           <cellValueFactory>
              <PropertyValueFactory property="symbol" />
           </cellValueFactory>
        </TableColumn>
        <TableColumn fx:id="weightCol" editable="true" prefWidth="191.0" text="Weight Fraction">
           <cellFactory>
              <TextFieldTableCell fx:factory="forTableColumn" />
           </cellFactory>
           <cellValueFactory>
              <PropertyValueFactory property="weight" />
           </cellValueFactory>
        </TableColumn>
        <TableColumn fx:id="atomCol" editable="true" prefWidth="189.0" text="Atom Fraction">
           <cellFactory>
              <TextFieldTableCell fx:factory="forTableColumn" />
           </cellFactory>
           <cellValueFactory>
              <PropertyValueFactory property="atom" />
           </cellValueFactory>
        </TableColumn>
     </columns>
     <items>
        <FXCollections fx:factory="observableArrayList">
           <Row atom="" symbol="" weight="" />
        </FXCollections>
     </items>
  </TableView>

表模型

public class Row{
    private final SimpleStringProperty symbol = new SimpleStringProperty("");
    private final SimpleStringProperty weight = new SimpleStringProperty("");
    private final SimpleStringProperty atom = new SimpleStringProperty("");

    /**
     * Default constructor, defaults to empty strings
     */
    public Row(){
        this("","","");
    }
    /**
     * 
     * @param s symbol(or ZA)
     * @param w weight fraction
     * @param a atom fraction (or atom count ending with "#")
     */
    public Row(String s, String w, String a){
        setSymbol(s);
        setWeight(w);
        setAtom(a);
    }

    public String getSymbol(){return symbol.get();}
    public String getWeight(){return weight.get();}
    public String getAtom(){return atom.get();}

    public void setSymbol(String s){symbol.set(s);}
    public void setWeight(String w){weight.set(w);}
    public void setAtom(String a){atom.set(a);}
}

状态1:执行任何操作之前

State 1: before doing anything

状态2:已编辑的单元格

State 2: edited cells

状态3:将行添加到表中,数据恢复编辑

State 3: adding row to table, data reverts edits

推荐答案

问题是您没有在Row类中提供属性访问器"方法.没有这些属性,PropertyValueFactoryTextFieldTableCell无法访问实际属性并绑定/监听它们以进行更改.因此,您的Row类应该看起来像

The issue is that you don't provide "property accessor" methods in your Row class. Without these, the PropertyValueFactory and the TextFieldTableCell cannot access the actual properties and bind/listen to them for changes.So your Row class should look like

public class Row{
    private final SimpleStringProperty symbol = new SimpleStringProperty("");
    private final SimpleStringProperty weight = new SimpleStringProperty("");
    private final SimpleStringProperty atom = new SimpleStringProperty("");

    /**
     * Default constructor, defaults to empty strings
     */
    public Row(){
        this("","","");
    }
    /**
     * 
     * @param s symbol(or ZA)
     * @param w weight fraction
     * @param a atom fraction (or atom count ending with "#")
     */
    public Row(String s, String w, String a){
        setSymbol(s);
        setWeight(w);
        setAtom(a);
    }

    public String getSymbol(){return symbol.get();}
    public String getWeight(){return weight.get();}
    public String getAtom(){return atom.get();}

    public void setSymbol(String s){symbol.set(s);}
    public void setWeight(String w){weight.set(w);}
    public void setAtom(String a){atom.set(a);}

    public StringProperty symbolProperty() {
        return symbol ;
    }

    public StringProperty weightProperty() {
        return weight ;
    }

    public StringProperty atomProperty() {
        return atom ;
    } 
}

有关更多详细信息,请检查 PropertyValueFactory 有关属性的教程部分(这只是JavaFX属性模式的一般背景).

For more details, check the API documentation for PropertyValueFactory and the tutorial section on properties (which is just general background on the JavaFX property pattern).

如果由于某种原因而无法提供这些方法(例如,您正在使用无法作为模型进行更改的现有类),则可以使用以下方法手动提供表格列编辑和模型之间的连线" TableColumn.setOnEditCommit(...)在您的控制器类中.尽管我建议尽可能使用属性访问器"来实现该模型,但以下内容应该可以使现有的Row类正常工作.

If, for some reason, you can't provide these methods (e.g. you are using existing classes you cannot change as your model), you can provide the "wiring" between the table column editing and the model by hand, using TableColumn.setOnEditCommit(...) in your controller class. The following should make things work with your existing Row class, though I recommend implementing the model with the "property accessors" whenever possible.

public void initialize(URL url, ResourceBundle rb) {
    // ...
    elementCol.setOnEditCommit(e -> {
        int rowIndex = e.getTablePosition().getRow();
        Row row = elementsTable.getItems().get(rowIndex);
        row.setElement(e.getNewValue());
    });

    // similarly for other columns...
}

这篇关于JavaFX Tableview不绑定/还原的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆