gpt4 book ai didi

java - TextField onEdit 监听器

转载 作者:行者123 更新时间:2023-11-30 08:13:53 30 4
gpt4 key购买 nike

我正在尝试在 javafx 中使用 TextField。场景:我有填充了特定对象的 ListView 和编辑按钮来编辑与 ListView 的列表单元格关联的对象。当我单击编辑按钮时,它会将我重定向到具有编辑功能的 Pane ,在其中我可以编辑该对象的名称并使用保存按钮保存它。所以我必须对保存按钮进行验证以使其启用和禁用。如果我在文本字段中编辑名称,那么它应该启用保存按钮,否则它应该保持禁用状态。我尝试在文本字段上使用不同的方法,如下所示。

textField.textPorperty.addListener(listener -> {
//Logic to enable disable save button
});

当我使用 ListView 时,此监听器为我提供旧值作为先前编辑的对象,该对象不满足我的条件。我无法使用

textField.focusedProperty().addListener((observableValue, oldValue, newValue) -> {});

因为它没有给我预期的行为。

谁能帮我解决这个问题吗?

最佳答案

您需要实现额外的逻辑来决定对 textProperty 的更改是否应更改按钮的启用状态。这需要:

  • 对初始值的引用(将文本设置为输入,例如更改列表中的选择)
  • 一个 boolean 属性,用于保持启用状态(下面称为缓冲)
  • 文本字段的监听器,根据需要更新启用状态

下面是一个非常简化的示例 - 只是为了帮助您入门 - 它将这些基础知识提取到一个名为 BufferedTextInput 的专用类中。缓冲在内部更改:

  • 如果设置了“主题”值或提交/放弃了更改,则设置为 false
  • 在第一次更改文本字段时收到通知后设置为 true

可以根据需要实现更复杂的逻辑(例如在检测到返回原始值的更改时不进行缓冲)。

/**
* Bind disable property of commit/cancel button to actual change.
* http://stackoverflow.com/q/29935643/203657
*/
public class ManualBufferingDemo extends Application {

private Parent getContent() {
ObservableList<Person> persons = FXCollections.observableList(Person.persons(),
person -> new Observable[] {person.lastNameProperty()});
ListView<Person> listView = new ListView<>(persons);

TextField lastName = new TextField();
Consumer<String> committer = text -> System.out.println("committing: " + text);
BufferedTextInput buffer = new BufferedTextInput(lastName, committer);
Button save = new Button("Save");
save.setOnAction(e -> {
buffer.commit();
});
save.disableProperty().bind(Bindings.not(buffer.bufferingProperty()));
Button cancel = new Button("Cancel");
cancel.setOnAction(e -> {
buffer.flush();
});
listView.getSelectionModel().selectedItemProperty().addListener((source, old, current) -> {
buffer.setSubject(current.lastNameProperty());
});
cancel.disableProperty().bind(Bindings.not(buffer.bufferingProperty()));
VBox content = new VBox(listView, lastName, save, cancel);
return content;
}


public static class BufferedTextInput {

private ReadOnlyBooleanWrapper buffering;
private StringProperty value;
private TextField input;
private Consumer<String> committer;

public BufferedTextInput(TextField input, Consumer<String> committer) {
buffering = new ReadOnlyBooleanWrapper(this, "buffering", false);
value = new SimpleStringProperty(this, "");
this.input = input;
this.committer = committer;
input.textProperty().addListener((source, old, current) -> {
updateState(old, current);
});
input.setOnAction(e -> commit());
}

private void updateState(String old, String current) {
if (isBuffering()) return;
if (value.get().equals(current)) return;
setBuffering(true);
}

public void setSubject(StringProperty value) {
this.value = value;
input.setText(value.get());
setBuffering(false);
}

public void commit() {
committer.accept(input.getText());
this.value.set(input.getText());
setBuffering(false);
}

public void flush() {
input.setText(value.get());
setBuffering(false);
}

public boolean isBuffering() {
return buffering.get();
}

public ReadOnlyBooleanProperty bufferingProperty() {
return buffering.getReadOnlyProperty();
}

private void setBuffering(boolean buffer) {
buffering.set(buffer);
}
}

@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(getContent()));
primaryStage.show();
}

public static void main(String[] args) {
launch(args);
}
}

对于生产使用, View 和模型之间的这种直接耦合(例如,当需要完整表单的缓冲时)还不够好,可能需要进一步分离。请参阅BufferedObjectProperty及其在臭名昭著的 AlbumManager 的 FX 改编中的使用示例(非常粗略)

关于java - TextField onEdit 监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29935643/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com