我有一个组合框,其中列出了设置的值。我已经使用 setEditable(true) 方法使其可编辑,但如何获取用户输入的值?我尝试了 getSelectionModel().getSelectedItem() 和 getValue() 方法但没有成功。
这是代码。
public class Comparator extends Application {
@Override
public void start(Stage stage) {
stage.setTitle("ComboBoxSample");
Scene scene = new Scene(new Group(), 450, 250);
ComboBox<String> emailComboBox = new ComboBox<>();
emailComboBox.getItems().addAll("A","B","C","D","E");
emailComboBox.setEditable(true);
Button b = new Button("get text");
GridPane grid = new GridPane();
grid.setVgap(4);
grid.setHgap(10);
grid.setPadding(new Insets(5, 5, 5, 5));
Label to = new Label("To: ");
Label selected = new Label();
grid.add(to, 0, 0);
grid.add(emailComboBox, 1, 0);
grid.add(b, 2, 0);
grid.add(selected, 3, 0);
b.setOnAction(e -> {
selected.setText(emailComboBox.????);
});
Group root = (Group) scene.getRoot();
root.getChildren().add(grid);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
其实我想获取新输入的值。 PS:只是为了避免混淆,以防万一。我可以输入列表中不存在的任何字符串。这将是输入的新值。
最佳答案
默认情况下,大多数 JavaFX 控件不会在失去焦点时“提交”值 - 因此 TextField
s,当用作较大控件(例如 ComboBox
)内的编辑控件时,不会将该值提交回父控件,除非用户按下 Enter。关于这个设计决定有很多争议:然而,这是已经做出的决定,如果我们要使用 JavaFX,我们必须要么接受它,要么找到解决它的方法以获得我们想要的行为。
一种“快速而肮脏”的方法是深入文本字段并从中获取文本,如@Ajeetkumar 的回答:
selected.setText(emailComboBox.getEditor().getText());
这种方法的问题在于它使应用程序处于不一致状态:标签中显示给用户的值不是组合框模型中保存的值:换句话说,emailComboBox.getValue()
返回一个不同的值显示在标签中的那个(因为文本字段中的值从未提交给组合框)。在某些时候,您的应用程序需要处理显示的数据,而程序员(或团队的其他成员)自然会在组合框的模型中查找数据:即他们希望数据在 emailComboBox.getValue()
中。更好的方法是确保组合框的值在您需要时更新,然后只使用预期的 emailComboBox.getValue()
来获取数据。
例如,您可以在文本字段失去焦点时更新值:
emailComboBox.getEditor().focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
if (! isNowFocused) {
emailComboBox.setValue(emailComboBox.getEditor().getText());
}
});
然后是自然的:
b.setOnAction(e -> {
selected.setText(emailComboBox.getValue());
});
通过这种方法,应用程序始终处于一致的状态:即标签显示组合框的值,这比直接从文本字段设置标签更不可能在以后引起错误。
另一种变体是在编辑器中的文本发生变化时立即更新组合框值:
emailComboBox.getEditor().textProperty().addListener((obs, oldText, newText) -> {
emailComboBox.setValue(newText);
});
请注意,如果您愿意,在这个版本中您实际上可以完全放弃按钮,而只需将标签的文本直接绑定(bind)到组合框的值:
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class Comparator extends Application {
@Override
public void start(Stage stage) {
stage.setTitle("ComboBoxSample");
Scene scene = new Scene(new Group(), 450, 250);
ComboBox<String> emailComboBox = new ComboBox<>();
emailComboBox.getItems().addAll("A","B","C","D","E");
emailComboBox.setEditable(true);
emailComboBox.getEditor().textProperty().addListener((obs, oldText, newText) -> {
emailComboBox.setValue(newText);
});
GridPane grid = new GridPane();
grid.setVgap(4);
grid.setHgap(10);
grid.setPadding(new Insets(5, 5, 5, 5));
Label to = new Label("To: ");
Label selected = new Label();
grid.add(to, 0, 0);
grid.add(emailComboBox, 1, 0);
grid.add(selected, 2, 0);
selected.textProperty().bind(emailComboBox.valueProperty());
Group root = (Group) scene.getRoot();
root.getChildren().add(grid);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
强烈建议保持数据的完整性以保持应用程序的一致性并减少以后引入错误的可能性,因此强烈建议更新组合框的 value
属性以包含您要表示的值,然后引用该值。用作编辑器的文本字段实际上是组合框的一个实现细节,只能用于修改组合框编辑过程的行为:在这个例子中,它用于修改更新行为——你也可以设置一个格式化程序它等。它不应该用作模型的代理,因为这会让以后的生活变得困难。
关于java - 如何在 JavaFx 的可编辑 ComboBox 中获取输入值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37923502/