编辑表的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());