How to bind TextField and String object in JavaFX?

12,078

First, modify your WordType class to use JavaFX properties:

public class WordType {

    private final StringProperty first = new SimpleStringProperty();
    private final StringProperty second = new SimpleStringProperty();

    public StringProperty firstProperty() {
        return first ;
    }

    public final String getFirst() {
        return firstProperty().get() ;
    }

    public final void setFirst(String first) {
        firstProperty().set(first);
    }


    public StringProperty secondProperty() {
        return second ;
    }

    public final String getSecond() {
        return secondProperty().get() ;
    }

    public final void setSecond(String second) {
        secondProperty().set(second);
    }
}

Now modify the list cell implementation so that it creates the text fields only once. When the item changes, bidirectionally bind the text fields to the properties in the new item:

list.setCellFactory(lv -> new ListCell<WordType>() {

    private final TextField word = new TextField();
    private final TextField translate = new TextField();
    private final ToolBar root = new ToolBar(word, new Separator(), translate);

    {
        // anonymous constructor:

        itemProperty().addListener((obs, oldWordType, newWordType) -> {
            if (oldWordType != null) {
                word.textProperty().unbindBidirectional(oldWordType.firstProperty());
                translate.textProperty().unbindBidirectional(oldWordType.secondProperty());
            }

            if (newWordType != null) {
                word.textProperty().bindBidirectional(newWordType.firstProperty());
                translate.textProperty().bindBidirectional(newWordType.secondProperty());
            }
        });
    }

    @Override
    protected void updateItem(WordType item, boolean empty) {
        super.updateItem(item, empty);
        setGraphic(empty ? null : root);
    }
});

If for some reason you are unable to change the implementation of WordType, then you can use some listeners on the text fields instead. Note this will only work one way: if the text in the text field changes, the WordType property will change; however if the WordType property changes from some other source while the cell is displayed, the cell will not update. Depending on your application requirements, this may or may not be an issue. The cell implementation in this case looks like:

list.setCellFactory(lv -> new ListCell<WordType>() {

    private final TextField word = new TextField();
    private final TextField translate = new TextField();
    private final ToolBar root = new ToolBar(word, new Separator(), translate);

    {
        // anonymous constructor:

        word.textProperty().addListener((obs, oldText, newText) -> {
            WordType wordType = getItem();
            wordType.setFirst(newText);
        });

        translate.textProperty().addListener((obs, oldText, newText) -> {
            WordType wordType = getItem();
            wordType.setSecond(newText);
        });
    }

    @Override
    protected void updateItem(WordType item, boolean empty) {
        super.updateItem(item, empty);
        setGraphic(empty ? null : root);
    }
});

with your existing WordType class (I assume you omitted the get and set methods for brevity).

Share:
12,078
Admin
Author by

Admin

Updated on June 04, 2022

Comments

  • Admin
    Admin almost 2 years

    I have some words which I show in TextField. I want to rewrite this words every time when this words have been changed in TextField. This is my type:

    class WordType {
       String first;
       String second;
    }
    

    and ListView where I show my words:

    ListView<WordType> list = new ListView<>();
    
    list.setCellFactory(lv -> new ListCell<WordType>() {
            @Override
            public void updateItem(WordType item, boolean empty){
                super.updateItem(item, empty);
                if (empty){
                    setText(null);
                } else {
                    ToolBar root = new ToolBar();
    
                    TextField word = new TextField(item.first);
    
                    TextField translate = new TextField(item.second);
    
                    root.getItems().addAll(word, new Separator(), translate);
                    setGraphic(root);
                }
            }
        });
    

    How change strings in WordType if I change these strings in TextField?

    Sorry, for my bad English =)