JavaFX Tableview not binding/reverting

雨燕双飞 提交于 2019-12-13 18:31:01

问题


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>

Table model

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

State 1: before doing anything

State 2: edited cells

State 3: adding row to table, data reverts edits


回答1:


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

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).

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...
}


来源:https://stackoverflow.com/questions/31269932/javafx-tableview-not-binding-reverting

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