【问题标题】:JavaFX Tableview not binding/revertingJavaFX Tableview不绑定/恢复
【发布时间】:2015-07-07 13:28:43
【问题描述】:

在诊断行为方面寻求帮助,因为我不知道它可能发生在哪里。

在表格编辑时,标签会更新,但值似乎永远不会更新,因为只要表格更新,值就会恢复。这发生在排序中,并且可以通过以下方式证明是正确的:

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

界面:

@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:在做任何事情之前

状态 2:已编辑单元格

状态 3:向表中添加行,数据还原编辑

【问题讨论】:

    标签: javafx tableview


    【解决方案1】:

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

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

    有关更多详细信息,请查看 API documentation for PropertyValueFactorytutorial section on properties(这只是 JavaFX 属性模式的一般背景知识)。

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

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

    【讨论】:

    • 我的上帝来自另一个没有提供这些的教程的代码。我最终只是为桌子的 onEdit 和那些工作而入侵了普通的 FX 监听器。对于未来的一切,这就是它所需要的一切吗?
    • 是的,有一些关于这些东西的教程写得不好(其中一些甚至在 Oracle 网站本身上)。
    • 如果您按照该模式定义模型类(即getX()setX(...)xProperty() 方法),一切都会更加顺利。如果您不能,推荐的TableView 方法是在表格列上注册onEditCommit 处理程序:我更新了答案以包含这种情况。如果您使用ListView,并且希望在属于列表中元素的属性发生更改时更新单元格,则可能需要使用“提取器”创建列表,请参阅stackoverflow.com/questions/23822550/…
    • 这就是我最终做的,我从 Oracle 教程中破解了它。
    猜你喜欢
    • 2012-08-28
    • 2012-05-28
    • 2013-09-08
    • 2013-03-31
    • 2023-03-12
    • 2016-06-12
    • 2015-03-06
    • 2014-08-06
    相关资源
    最近更新 更多