编辑表的javafx绑定代码片段不';我不工作

编辑表的javafx绑定代码片段不';我不工作,javafx,classcastexception,Javafx,Classcastexception,我使用此代码段完成了表的编辑提交。 我的问题是我得到了一个 Caused by: java.lang.ClassCastException: javafx.beans.property.ReadOnlyObjectWrapper cannot be cast to javafx.beans.property.SimpleStringProperty 在这方面: SimpleStringProperty sp = (SimpleStringProperty)ov; 我不知道我能做些

我使用此代码段完成了表的编辑提交。

我的问题是我得到了一个

Caused by: java.lang.ClassCastException: javafx.beans.property.ReadOnlyObjectWrapper cannot be cast to javafx.beans.property.SimpleStringProperty
在这方面:

     SimpleStringProperty sp = (SimpleStringProperty)ov;
我不知道我能做些什么。 我的数据类只使用SimpleStringProperty值

以下是完整的代码:

import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TextArea;
import javafx.util.Callback;

import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;

public class Supermain extends Application {



    @Override
    public void start(Stage primaryStage) {

        final TableView<myTextRow> table = new TableView<>();
        table.setEditable(true);
        table.setStyle("-fx-text-wrap: true;");

        //Table columns
        TableColumn<myTextRow, String> clmID = new TableColumn<>("ID");
        clmID.setMinWidth(160);
        clmID.setCellValueFactory(new PropertyValueFactory<>("ID"));


        TableColumn<myTextRow, String> clmtext = new TableColumn<>("Text");
        clmtext.setMinWidth(160);
        clmtext.setCellValueFactory(new PropertyValueFactory<>("text"));
        clmtext.setCellFactory(new TextFieldCellFactory());

        //Add data
        final ObservableList<myTextRow> data = FXCollections.observableArrayList(
                new myTextRow(5, "Lorem"),
                new myTextRow(2, "Ipsum")
        );
        table.setItems(data);
        table.getColumns().addAll(clmID, clmtext);

        HBox hBox = new HBox();
        hBox.setSpacing(5.0);
        hBox.setPadding(new Insets(5, 5, 5, 5));

        Button btn = new Button();
        btn.setText("Get Data");
        btn.setOnAction(new EventHandler<ActionEvent>() {

            @Override
            public void handle(ActionEvent event) {
                for (myTextRow data1 : data) {
                    System.out.println("data:"+data1.getText());
                }
            }
        });

        hBox.getChildren().add(btn);


        BorderPane pane = new BorderPane();
        pane.setTop(hBox);
        pane.setCenter(table);
        primaryStage.setScene(new Scene(pane, 640, 480));
        primaryStage.show();

    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    public static class TextFieldCellFactory
            implements Callback<TableColumn<myTextRow, String>, TableCell<myTextRow, String>> {


        @Override
        public TableCell<myTextRow, String> call(TableColumn<myTextRow, String> param) {
            TextFieldCell textFieldCell = new TextFieldCell();
            return textFieldCell;
        }

        public static class TextFieldCell extends TableCell<myTextRow, String> {

            private TextArea textField;
            private StringProperty boundToCurrently = null;


            public TextFieldCell() {
                String strCss;
                // Padding in Text field cell is not wanted - we want the Textfield itself to "be"
                // The cell.  Though, this is aesthetic only.  to each his own.  comment out
                // to revert back.  
                strCss = "-fx-padding: 0;";

                this.setStyle(strCss);

                textField = new TextArea();
                textField.setWrapText(true);
                textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);



                //textField.setPrefHeight(real_lines_height(textField.getText(),this.getWidth(),30,23));
                // 
                // Default style pulled from caspian.css. Used to play around with the inset background colors
                // ---trying to produce a text box without borders
                strCss = ""
                        + //"-fx-background-color: -fx-shadow-highlight-color, -fx-text-box-border, -fx-control-inner-background;" +
                        "-fx-background-color: -fx-control-inner-background;"
                        + //"-fx-background-insets: 0, 1, 2;" +
                        "-fx-background-insets: 0;"
                        + //"-fx-background-radius: 3, 2, 2;" +
                        "-fx-background-radius: 0;"
                        + // "-fx-padding: 3 5 3 5;" +   /*Play with this value to center the text depending on cell height??*/
                        "-fx-padding: 0 0 0 0;"
                        + /*Play with this value to center the text depending on cell height??*/ //"-fx-padding: 0 0 0 0;" +
                        "-fx-prompt-text-fill: derive(-fx-control-inner-background,-30%);"
                        + "-fx-cursor: text;"
                        + "";

                // Focused and hover states should be set in the CSS.  This is just a test
                // to see what happens when we set the style in code
                textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
                    @Override
                    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                        TextArea tf = (TextArea) getGraphic();
                        // System.out.println(".changed() index : "+  get_ID_from_table_index(getIndex()));

                        String strStyleGotFocus = "-fx-background-color: blue, -fx-text-box-border, -fx-control-inner-background;"
                                + "-fx-background-insets: -0.4, 1, 2;"
                                + "-fx-background-radius: 3.4, 2, 2;";
                        String strStyleLostFocus
                                = //"-fx-background-color: -fx-shadow-highlight-color, -fx-text-box-border, -fx-control-inner-background;" +
                                "-fx-background-color: -fx-control-inner-background;"
                                + //"-fx-background-insets: 0, 1, 2;" +
                                "-fx-background-insets: 0;"
                                + //"-fx-background-radius: 3, 2, 2;" +
                                "-fx-background-radius: 0;"
                                + //"-fx-padding: 3 5 3 5;" +   /**/
                                "-fx-padding: 0 0 0 0;"
                                + /**/ //"-fx-padding: 0 0 0 0;" +
                                "-fx-prompt-text-fill: derive(-fx-control-inner-background,-30%);"
                                + "-fx-cursor: text;"
                                + "";
                        if (newValue.booleanValue()) {
                            tf.setStyle(strStyleGotFocus);
                        } else {
                            tf.setStyle(strStyleLostFocus);
                        }

                        if(!newValue)
                        {                                                                          


                            System.out.println("EDITABLE???? "+isEditing());
                           System.out.println("TEXT:::: "+textField.getText());
                        //    commitEdit(textField.getText());

                        }

                    }
                });
                textField.hoverProperty().addListener(new ChangeListener<Boolean>() {

                    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {

                        TextArea tf = (TextArea) getGraphic();
                        String strStyleGotHover = "-fx-background-color: derive(blue,90%), -fx-text-box-border, derive(-fx-control-inner-background, 10%);"
                                + "-fx-background-insets: 1, 2.8, 3.8;"
                                + "-fx-background-radius: 3.4, 2, 2;";
                        String strStyleLostHover
                                = //"-fx-background-color: -fx-shadow-highlight-color, -fx-text-box-border, -fx-control-inner-background;" +
                                "-fx-background-color: -fx-control-inner-background;"
                                + //"-fx-background-insets: 0, 1, 2;" +
                                "-fx-background-insets: 0;"
                                + //"-fx-background-radius: 3, 2, 2;" +
                                "-fx-background-radius: 0;"
                                + //"-fx-padding: 3 5 3 5;" +   /**/
                                "-fx-padding: 0 0 0 0;"
                                + "-fx-prompt-text-fill: derive(-fx-control-inner-background,-30%);"
                                + "-fx-cursor: text;"
                                + "";
                        String strStyleHasFocus = "-fx-background-color: blue, -fx-text-box-border, -fx-control-inner-background;"
                                + "-fx-background-insets: -0.4, 1, 2;"
                                + "-fx-background-radius: 3.4, 2, 2;";

                        if (newValue.booleanValue()) {
                            tf.setStyle(strStyleGotHover);



                        } else if (!tf.focusedProperty().get()) {
                            tf.setStyle(strStyleLostHover);
                        } else {
                            tf.setStyle(strStyleHasFocus);
                        }

                    }
                }); 

                textField.textProperty().addListener(e -> {
                    double height = 25;
                    textField.setPrefHeight(height);
                    textField.setMaxHeight(height);


                    //System.out.println("textfield Parent: "+textField.getParent().toString()); 
                });
                textField.setStyle(strCss);
                this.setGraphic(textField);
            }

            @Override
    protected void updateItem(String item, boolean empty) {
      super.updateItem(item, empty);        
      if(!empty) {
        // Show the Text Field
        this.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);

        // Retrieve the actual String Property that should be bound to the TextField
        // If the TextField is currently bound to a different StringProperty
        // Unbind the old property and rebind to the new one
       ObservableValue<String> ov = getTableColumn().getCellObservableValue(getIndex());
        SimpleStringProperty sp = (SimpleStringProperty)ov;

        if(this.boundToCurrently==null) {
            this.boundToCurrently = sp;
            this.textField.textProperty().bindBidirectional(sp);
        }
        else {
            if(this.boundToCurrently != sp) {
              this.textField.textProperty().unbindBidirectional(this.boundToCurrently);
              this.boundToCurrently = sp;
              this.textField.textProperty().bindBidirectional(this.boundToCurrently);
            }
        }
        System.out.println("item=" + item + " ObservableValue<String>=" + ov.getValue());
        //this.textField.setText(item);  // No longer need this!!!
      }
      else {
        this.setContentDisplay(ContentDisplay.TEXT_ONLY);
      }
    }

        }


    }

    public class myTextRow {

        private final SimpleIntegerProperty ID;

        private final SimpleStringProperty text;

        public myTextRow(int ID, String text) {

            this.ID = new SimpleIntegerProperty(ID);
            this.text = new SimpleStringProperty(text);

        }

        public void setID(int id) {
            this.ID.set(id);
        }

        public void setText(String text) {
            this.text.set(text);
        }

        public int getID() {
            return ID.get();
        }

        public String getText() {
            return text.get();
        }
    }
}
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.property.StringProperty;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.scene.control.ContentDisplay;
导入javafx.scene.control.TableCell;
导入javafx.scene.control.TableColumn;
导入javafx.scene.control.TextArea;
导入javafx.util.Callback;
导入javafx.application.application;
导入静态javafx.application.application.launch;
导入javafx.beans.property.SimpleIntegerProperty;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.event.ActionEvent;
导入javafx.event.EventHandler;
导入javafx.geometry.Insets;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.TableView;
导入javafx.scene.control.cell.PropertyValueFactory;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.HBox;
导入javafx.stage.stage;
公共类Supermain扩展应用程序{
@凌驾
公共无效开始(阶段primaryStage){
最终的TableView表格=新的TableView();
table.setEditable(true);
表.setStyle(“-fx文本换行符:true;”);
//表列
TableColumn clmID=新的TableColumn(“ID”);
clmID.setMinWidth(160);
clmID.setCellValueFactory(新属性ValueFactory(“ID”);
TableColumn clmtext=新的TableColumn(“文本”);
clmtext.setMinWidth(160);
clmtext.setCellValueFactory(新属性ValueFactory(“文本”);
setCellFactory(新的TextFieldCellFactory());
//添加数据
最终ObservableList数据=FXCollections.observableArrayList(
新myTextRow(5,“Lorem”),
新myTextRow(2,“Ipsum”)
);
表2.设置项目(数据);
table.getColumns().addAll(clmID、clmtext);
HBox HBox=新的HBox();
hBox.setspace(5.0);
hBox.设置填充(新插图(5,5,5,5));
按钮btn=新按钮();
btn.setText(“获取数据”);
btn.setOnAction(新的EventHandler(){
@凌驾
公共无效句柄(ActionEvent事件){
用于(myTextRow数据1:数据){
System.out.println(“数据:+data1.getText());
}
}
});
hBox.getChildren().add(btn);
BorderPane=新的BorderPane();
窗格。机顶盒(hBox);
窗格。设置中心(表);
初始阶段。设置场景(新场景(窗格,640480));
primaryStage.show();
}
/**
*@param指定命令行参数
*/
公共静态void main(字符串[]args){
发射(args);
}
公共静态类TextFieldCellFactory
实现回调{
@凌驾
公共TableCell调用(TableColumn参数){
TextFieldCell TextFieldCell=新的TextFieldCell();
返回文本字段单元格;
}
公共静态类TextFieldCell扩展了TableCell{
私有文本区文本域;
private StringProperty BoundToCurrent=null;
公共TextFieldCell(){
弦式结构;
//不需要在文本字段单元格中填充-我们希望文本字段本身“为”
//牢房。不过,这只是审美。每个人都有自己的。评论出来
//恢复原状。
strCss=“-fx填充:0;”;
本.设置方式(strCss);
textField=新的TextArea();
textField.setWrapText(true);
textField.setMinWidth(this.getWidth()-this.getGraphicTextGap()*2);
//setPrefHeight(实线高度(textField.getText(),this.getWidth(),30,23));
// 
//从caspian.css中提取的默认样式。用于使用插入的背景色
//---尝试生成无边框的文本框
strCss=“”
+//“-fx背景颜色:-fx阴影高亮显示颜色,-fx文本框边框,-fx控件内部背景;”+
“-fx背景色:-fx控件内部背景;”
+//“-fx背景插图:0、1、2;”+
“-fx背景插图:0;”
+/“-fx背景半径:3,2,2;”+
“-fx背景半径:0;”
+//“-fx padding:35;“+/*根据单元格高度使用此值将文本居中*/
“-fx填充:0;”
+/*根据单元格高度,使用此值使文本居中???*/“-fx padding:0;”+
“-fx提示文本填充:派生(-fx控件内部背景,-30%)
+“-fx光标:文本;”
+ "";
//聚焦和悬停状态应该在CSS中设置。这只是一个测试
//查看在代码中设置样式时会发生什么
textField.focusedProperty().addListener(新的ChangeListener()){
@凌驾

public void changed(observeValue您的模型类缺少“属性访问器”。因此,
PropertyValueFactory
无法使用属性本身。如中所述:

如何使用此类的示例如下:

TableColumn<Person,String> firstNameCol = new TableColumn<Person,String>("First Name"); 
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person,String>("firstName"));   
然后你可以定义你的单元格值工厂为

TableColumn<myTextRow, Number> clmID = new TableColumn<>("ID");
clmID.setMinWidth(160);
clmID.setCellValueFactory(new PropertyValueFactory<>("id"));


TableColumn<myTextRow, String> clmtext = new TableColumn<>("Text");
clmtext.setMinWidth(160);
clmtext.setCellValueFactory(new PropertyValueFactory<>("text"));
TableColumn clmID=新的TableColumn(“ID”);
clmID.setMinWidth(160);
clmID.setCellValueFactory(新属性ValueFactory(“id”);
TableColumn clmtext=新Ta
TableColumn<myTextRow, Number> clmID = new TableColumn<>("ID");
clmID.setMinWidth(160);
clmID.setCellValueFactory(new PropertyValueFactory<>("id"));


TableColumn<myTextRow, String> clmtext = new TableColumn<>("Text");
clmtext.setMinWidth(160);
clmtext.setCellValueFactory(new PropertyValueFactory<>("text"));
TableColumn<myTextRow, Number> clmID = new TableColumn<>("ID");
clmID.setMinWidth(160);
clmID.setCellValueFactory(cellData -> cellData.getValue().idProperty());


TableColumn<myTextRow, String> clmtext = new TableColumn<>("Text");
clmtext.setMinWidth(160);
clmtext.setCellValueFactory(cellData -> cellData.getValue().textProperty());