E. Muuli
E. Muuli

Reputation: 4340

Select JavaFX Editable Combobox text on click

I have a question regarding text selection when clicking on the editable Combobox.

Currently what happens, is that the mouse cursor just goes to that place of the input and does not select the whole text field. I would like to highlight/select whole textfield on the click, but it doesn't do that.

What I want that a click on the textfield would do:

Image

This is my AutoComplete class:

public class AutoCompleteComboBoxListener<T> implements EventHandler<KeyEvent> {

private ComboBox comboBox;
private StringBuilder sb;
private ObservableList<T> data;
private boolean moveCaretToPos = false;
private int caretPos;
private Button button;

public AutoCompleteComboBoxListener(final ComboBox comboBox, final Button button) {
    this.comboBox = comboBox;
    sb = new StringBuilder();
    data = comboBox.getItems();

    this.comboBox.setEditable(true);

    this.button = button;

    this.comboBox.setOnKeyPressed(new EventHandler<KeyEvent>() {

        @Override
        public void handle(KeyEvent t) {
            System.out.println("misaja");
            System.out.println(t);

            comboBox.hide();
        }
    });
    this.comboBox.setOnKeyReleased(AutoCompleteComboBoxListener.this);
}

@Override
public void handle(KeyEvent event) {

    System.out.println("nonoh");
    System.out.println(event.getCode());
    UI.bitLogger.logging(String.valueOf(event.getCode()));

    if (event.getCode() == (KeyCode.ENTER)) {
        System.out.println("erki");
        button.fire();
    }

    if (event.getCode() == KeyCode.UP) {
        caretPos = -1;
        moveCaret(comboBox.getEditor().getText().length());
        return;
    } else if (event.getCode() == KeyCode.DOWN) {
        if (!comboBox.isShowing()) {
            comboBox.show();
        }
        caretPos = -1;
        moveCaret(comboBox.getEditor().getText().length());
        return;
    } else if (event.getCode() == KeyCode.BACK_SPACE) {
        moveCaretToPos = true;
        caretPos = comboBox.getEditor().getCaretPosition();
    } else if (event.getCode() == KeyCode.DELETE) {
        moveCaretToPos = true;
        caretPos = comboBox.getEditor().getCaretPosition();
    }

    if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT
            || event.isControlDown() || event.getCode() == KeyCode.HOME
            || event.getCode() == KeyCode.END || event.getCode() == KeyCode.TAB) {
        return;
    }

    ObservableList list = FXCollections.observableArrayList();
    for (int i = 0; i < data.size(); i++) {
        if (data.get(i).toString().toLowerCase().startsWith(
                AutoCompleteComboBoxListener.this.comboBox
                        .getEditor().getText().toLowerCase())) {
            list.add(data.get(i));
        }
    }
    String t = comboBox.getEditor().getText();

    comboBox.setItems(list);
    comboBox.getEditor().setText(t);
    if (!moveCaretToPos) {
        caretPos = -1;
    }
    moveCaret(t.length());
    if (!list.isEmpty()) {
        comboBox.show();
    }
}

private void moveCaret(int textLength) {
    if (caretPos == -1) {
        comboBox.getEditor().positionCaret(textLength);
    } else {
        comboBox.getEditor().positionCaret(caretPos);
    }
    moveCaretToPos = false;
}

I am creating the ComboBox here:

    final ComboBox comboBox = new ComboBox(options);
    comboBox.setPrefWidth(320);

    comboBox.setValue("");

    //ComboBox comboBox = new ComboBox();

    new AutoCompleteComboBoxListener<>(comboBox, goButton);

    comboBox.addEventFilter(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() {
        @Override
        public void handle(KeyEvent ke) {
            if (ke.getCode() == KeyCode.ENTER) {
                //System.out.println("ENTER was released");
                goButton.fire();
            }
        }
    });

    comboBox.addEventFilter(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>() {
        @Override
        public void handle(MouseEvent mouseEvent) {
            System.out.println("mouse click detected2! " + mouseEvent.getSource());
            //comboBox.getEditor().requestFocus();
            //comboBox.getEditor().requestFocus();
            //comboBox.requestFocus();
            //comboBox.getEditor().selectAll();
            //comboBox.requestFocus();
            //None of these seem to work.
        }
    });

What I added now is this:

 comboBox.getEditor().focusedProperty().addListener(new ChangeListener<Boolean>()
    {
        @Override
        public void changed(ObservableValue<? extends Boolean> arg0, Boolean oldPropertyValue, Boolean newPropertyValue)
        {
            if (newPropertyValue)
            {
                System.out.println("Textfield on focus");
                comboBox.requestFocus();
                comboBox.getEditor().selectAll();
            }
            else
            {
                System.out.println("Textfield out focus");
            }
        }
    });

But all it does is that it selects/highlights the text for just a moment and then removes the highlight once again.

Upvotes: 1

Views: 1380

Answers (1)

Nicolas Filotto
Nicolas Filotto

Reputation: 45005

You should try to do it by adding a focus listener on the textfield as next:

comboBox.getEditor().focusedProperty().addListener(
    (observable, oldValue, newValue) -> {
        if (newValue) {
            // Select the content of the field when the field gets the focus.
            Platform.runLater(comboBox.getEditor()::selectAll);
        }
    }
);

This code is for Java 8, for previous versions the corresponding code is:

comboBox.getEditor().focusedProperty().addListener(
    new ChangeListener<Boolean>() {
        @Override
        public void changed(final ObservableValue<? extends Boolean> observable, 
                            final Boolean oldValue, final Boolean newValue) {
            if (newValue) {
                Platform.runLater(
                    new Runnable() {
                        @Override
                        public void run() {
                            comboBox.getEditor().selectAll();
                        }
                    }
                );
            }
        }
    }
);

Upvotes: 1

Related Questions