Java TabeView的非个人文本字段
我想在JavaFX中为TableCell使用一个类(TextField)。这个类应该被普遍使用。一周来我一直在寻找解决方案,并在互联网上查看了各种解决方案 我目前的问题是,我可以在TabeView中显示数据,但更改不会到达控制器,即不会保存在数据类中,我也不知道为什么会这样,特别是因为我已经为数据选择器设计了类似的结构,而且它工作得很好 我希望能够控制TabeView中的行为,这也适用于我的类,但是如果数据没有存储在控制器中的数据类中,它又有什么好处呢 目前,我可以在TabeView中查看数据类中的值,并根据类中的设置对其进行编辑,但我无法将数据放入控制器中的数据类中 以下是我目前的做法: 控制器Java TabeView的非个人文本字段,java,javafx,textfield,Java,Javafx,Textfield,我想在JavaFX中为TableCell使用一个类(TextField)。这个类应该被普遍使用。一周来我一直在寻找解决方案,并在互联网上查看了各种解决方案 我目前的问题是,我可以在TabeView中显示数据,但更改不会到达控制器,即不会保存在数据类中,我也不知道为什么会这样,特别是因为我已经为数据选择器设计了类似的结构,而且它工作得很好 我希望能够控制TabeView中的行为,这也适用于我的类,但是如果数据没有存储在控制器中的数据类中,它又有什么好处呢 目前,我可以在TabeView中查看数据类
columnCourse.setCellValueFactory(新的PropertyValueFactory(“CourseName”);
setCellFactory(i->new CellClassTextFieldString(columnCourse,20));
setOnEditCommit(e->{System.out.println(“在控制器中提交”);});
TextFieldClass
公共类CellClassTextFieldString扩展了TableCell{
私有最终文本字段文本字段;
私人最终int maxLen;
公共CellClassTextFieldString(表列stringCol,整数maxLen){
this.textField=新的textField();
this.maxLen=maxLen;
this.textField.setTextFormatter(新的TextFormatter(新的StringConverter)(){
@凌驾
公共字符串到字符串(字符串对象){
如果(object==null)返回“”;
if(object.length()>maxLen){
返回object.substring(0,maxLen);
}否则{
返回对象;
}
}
@凌驾
公共字符串fromString(字符串字符串){
if(字符串==null){
返回“”;
}否则{
if(string.length()>maxLen){
返回string.substring(0,maxLen);
}否则{
返回字符串;
}
}
}
}));
editableProperty().bind(stringCol.editableProperty());
contentDisplayProperty().bind(绑定
.when(editableProperty())
.then(仅限ContentDisplay.GRAPHIC_)
。否则(仅限ContentDisplay.TEXT_)
);
setListener();
}
@凌驾
受保护的void updateItem(字符串strInput,布尔空){
System.out.println(“updateItem”);
super.updateItem(strInput,空);
if(空){
setText(空);
设置图形(空);
}否则{
this.textField.setText(strInput);
setGraphic(this.textField);
if(strInput==null){
setText(“”);
}否则{
setText(strInput);
}
}
}
私有void setListener(){
this.textField.focusedProperty().addListener((可观察、旧值、新值)->{
如果(新值){
System.out.println(“获取焦点”);
}否则{
System.out.println(“失去焦点”);
committedit(textField.getText());
}
});
this.textField.textProperty().addListener((可观察、旧值、新值)->{
System.out.println(“commit:+newValue+”isEditing:+isEditing());
if(newValue.length()>maxLen){
textField.setText(oldValue);
}
});
this.textField.setOnKeyPressed(新的EventHandler(){
@覆盖公共无效句柄(KeyEvent evt){
if(KeyCode.ESCAPE==evt.getCode()){
System.out.println(“取消编辑”);
取消编辑();
}
if(KeyCode.ENTER==evt.getCode()| | KeyCode.TAB==evt.getCode()){
System.out.println(“提交编辑”);
committedit(textField.getText());
}
}
});
}
}
我可以清楚地注意到的一个问题是contentDisplayProperty的绑定。是否只有在编辑时才需要文本字段?如果是这种情况,则需要使用只读编辑属性而不是可编辑属性进行绑定
contentDisplayProperty().bind(Bindings
.when(editingProperty())
.then(ContentDisplay.GRAPHIC_ONLY)
.otherwise(ContentDisplay.TEXT_ONLY)
);
下面是可以工作的修改后的单元实现。(至少对我有用:-)
class CellClassTextFieldString扩展了TableCell{
私有文本字段文本字段;
私人最终int maxLen;
公共CellClassTextFieldString(表列stringCol,整数maxLen){
this.maxLen=maxLen;
editableProperty().bind(stringCol.editableProperty());
contentDisplayProperty().bind(绑定
.when(编辑属性())
.then(仅限ContentDisplay.GRAPHIC_)
。否则(仅限ContentDisplay.TEXT_)
);
}
@凌驾
受保护的void updateItem(字符串strInput,布尔空){
System.out.println(“updateItem”);
super.updateItem(strInput,空);
if(空){
setText(空);
设置图形(空);
}否则{
if(isEditing()){
if(textField!=null){
setText(getItem());
}
设置图形(文本字段);
}否则
class CellClassTextFieldString<T> extends TableCell<T, String> {
private TextField textField;
private final int maxLen;
public CellClassTextFieldString(TableColumn<T, String> stringCol, Integer maxLen) {
this.maxLen = maxLen;
editableProperty().bind(stringCol.editableProperty());
contentDisplayProperty().bind(Bindings
.when(editingProperty())
.then(ContentDisplay.GRAPHIC_ONLY)
.otherwise(ContentDisplay.TEXT_ONLY)
);
}
@Override
protected void updateItem(String strInput, boolean empty) {
System.out.println("updateItem");
super.updateItem(strInput, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getItem());
}
setGraphic(textField);
} else {
setText(getItem());
}
}
}
@Override
public final void cancelEdit() {
super.cancelEdit();
setText(getItem());
}
@Override
public final void commitEdit(final String newValue) {
super.commitEdit(newValue);
}
@Override
public final void startEdit() {
super.startEdit();
if (textField == null) {
createTextField();
}
setGraphic(textField);
textField.setText(getItem());
textField.selectAll();
textField.requestFocus();
}
private void createTextField() {
this.textField = new TextField();
this.textField.setTextFormatter(new TextFormatter<>(new StringConverter<String>() {
@Override
public String toString(String object) {
if (object == null) return "";
if (object.length() > maxLen) {
return object.substring(0, maxLen);
} else {
return object;
}
}
@Override
public String fromString(String string) {
if (string == null) {
return "";
} else {
if (string.length() > maxLen) {
return string.substring(0, maxLen);
} else {
return string;
}
}
}
}));
this.textField.focusedProperty().addListener((observable, oldValue, newValue) -> {
if (!newValue) {
System.out.println("lost focus");
commitEdit(textField.getText());
}
});
this.textField.textProperty().addListener((observable, oldValue, newValue) -> {
if (newValue.length() > maxLen) {
textField.setText(oldValue);
}
});
this.textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent evt) {
if (KeyCode.ESCAPE == evt.getCode()) {
System.out.println("cancel edit");
cancelEdit();
}
if (KeyCode.ENTER == evt.getCode() || KeyCode.TAB == evt.getCode()) {
System.out.println("commit edit");
commitEdit(textField.getText());
}
}
});
}
}
columnCourse.setOnEditCommit(e -> {
System.out.println("Commit in Controller ");
( e.getTableView().getItems().get(
e.getTablePosition().getRow())
).set<Name>(e.getNewValue());
});