java 如何在 JavaFx 的可编辑 ComboBox 中获取输入值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37923502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 02:57:19  来源:igfitidea点击:

How to get entered value in editable ComboBox in JavaFx?

javajavafxcombobox

提问by Ajeetkumar

I have a ComboBox which lists the values set. I have made it editable using setEditable(true) method but how to get the value entered by user? I tried getSelectionModel().getSelectedItem() and getValue() method but didn't succeed.

我有一个 ComboBox,它列出了设置的值。我已使用 setEditable(true) 方法使其可编辑,但如何获取用户输入的值?我尝试了 getSelectionModel().getSelectedItem() 和 getValue() 方法但没有成功。

Here is the code.

这是代码。

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);
    }
}

I actually want to get the newly entered value. PS: Just to avoid the confusion if in case. I can enter any String which doesn't exist in the list already. this will be a new value entered.

我实际上想获得新输入的值。PS:以防万一是为了避免混淆。我可以输入列表中不存在的任何字符串。这将是一个输入的新值。

回答by James_D

By default, most JavaFX controls don't "commit" a value on losing focus - so TextFields, when used as editing controls inside a larger control such as a ComboBoxdon't commit the value back to the parent control unless the user presses Enter. There is quite a lot of controversy about this design decision: however it is the decision that was made and if we are to use JavaFX we have to either accept that or find ways to work around it to get the behavior we want.

默认情况下,大多数 JavaFX 控件不会在失去焦点时“提交”值 - 因此TextField,当用作较大控件内的编辑控件时,例如ComboBox不要将值提交回父控件,除非用户按下Enter。关于这个设计决定有很多争议:然而,这是做出的决定,如果我们要使用 JavaFX,我们必须要么接受它,要么找到解决它的方法以获得我们想要的行为。

One "quick and dirty" approach would be to dig into the text field and get the text from it, as in @Ajeetkumar's answer:

一种“快速而肮脏”的方法是深入文本字段并从中获取文本,如@Ajeetkumar 的回答所示:

selected.setText(emailComboBox.getEditor().getText());

The problem with this approach is that it leaves the application in an inconsistent state: the value displayed to the user in the label is not the value held in the model of the combo box: in other words emailComboBox.getValue()returns a different value to the one displayed in the label (since the value from the text field was never committed to the combo box). At some point your application will need to process the data displayed, and the natural place the programmer (or another member of the team) will look for the data is in the combo box's model: i.e. they will expect the data to be in emailComboBox.getValue(). A better approach is to make sure the combo box's value updates when you want it to, and then just use the expected emailComboBox.getValue()to get the data.

这种方法的问题在于它使应用程序处于不一致的状态:在标签中显示给用户的值不是组合框模型中保存的值:换句话说,emailComboBox.getValue()返回与显示在标签中的值不同的值标签(因为文本字段中的值从未提交到组合框)。在某些时候,您的应用程序将需要处理显示的数据,而程序员(或团队的其他成员)寻找数据的自然位置是在组合框的模型中:即,他们希望数据在emailComboBox.getValue(). 更好的方法是确保组合框的值在您需要时更新,然后只使用预期emailComboBox.getValue()来获取数据。

For example, you could update the value when the text field loses focus:

例如,您可以在文本字段失去焦点时更新值:

    emailComboBox.getEditor().focusedProperty().addListener((obs, wasFocused, isNowFocused) -> {
        if (! isNowFocused) {
            emailComboBox.setValue(emailComboBox.getEditor().getText());
        }
    });

and then the natural:

然后是自然:

    b.setOnAction(e -> {
        selected.setText(emailComboBox.getValue());
    });

With this approach, the application is always in a consistent state: i.e. the label is displaying the value of the combo box, which is far less likely to cause bugs later on than setting the label directly from the text field.

使用这种方法,应用程序始终处于一致状态:即标签显示组合框的值,与直接从文本字段设置标签相比,这在以后导致错误的可能性要小得多。

Another variation is to update the combo box value as soon as the text in the editor changes:

另一种变体是在编辑器中的文本发生更改时立即更新组合框值:

    emailComboBox.getEditor().textProperty().addListener((obs, oldText, newText) -> {
        emailComboBox.setValue(newText);
    });

Note that, if you wanted, with this version you could actually dispense with the button entirely and just bind the label's text directly to the combo box's value:

请注意,如果您愿意,使用此版本实际上可以完全省去按钮,而只需将标签的文本直接绑定到组合框的值:

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);
    }
}

Keeping the integrity of the data is highly recommended for keeping the application consistent and making it less likely to introduce bugs later on, so it's highly recommended to update the combo box's valueproperty to contain the value you want to represent, and then to refer to that value. The text field used as an editor is really an implementation detail of the combo box that should only be used to modify the behavior of the combo box editing process: in this example it's used to modify the update behavior - you could also set a formatter on it, etc. It shouldn't be used as a proxy for the model, as this will make life difficult later.

强烈建议保持数据的完整性,以保持应用程序一致并减少以后引入错误的可能性,因此强烈建议更新组合框的value属性以包含您要表示的值,然后引用该属性价值。用作编辑器的文本字段实际上是组合框的一个实现细节,应该只用于修改组合框编辑过程的行为:在本例中,它用于修改更新行为 - 您还可以在它,等等。它不应该被用作模型的代理,因为这会让以后的生活变得困难。

回答by Ajeetkumar

I got the answer.

我得到了答案。

emailComboBox.getEditor().getText()

emailComboBox.getEditor().getText()

The textField where we type in an editable ComboBox is known as the editorof the ComboBox. And it's a normal TextField object. To access that object, you need to use the method ComboBox.getEditor(). This way you can use the methods of the TextField class.

我们在可编辑 ComboBox 中键入的 textField 称为 ComboBox 的编辑器。它是一个普通的 TextField 对象。要访问该对象,您需要使用ComboBox.getEditor()方法。这样您就可以使用 TextField 类的方法。

回答by JakesIV

This will change the list as you change the editor value

这将在您更改编辑器值时更改列表

pluginConfig.getEditor().textProperty().addListener((obs, oldText, newText) -> {
        if (pluginConfig.getSelectionModel().getSelectedIndex() >= 0)
            pluginConfig.getItems().set(pluginConfig.getSelectionModel().getSelectedIndex(),newText);
    });

回答by Kamran

Try this:

试试这个:

String surName=cmbSurName.getSelectionModel().getSelectedItem().toString();
System.out.println(surName);

回答by ck1

You can use the following line of code to get the selected value in the ComboBox, and set in on the Label:

您可以使用以下代码行获取 中的选定值ComboBox,并在 中设置Label

selected.setText(emailComboBox.getValue());

Since you're using strings, you should also set the parameterized type of the ComboBoxas follows:

由于您使用的是字符串,您还应该ComboBox如下设置参数化类型:

ComboBox<String> emailComboBox = new ComboBox<>();