2 Replies Latest reply on Nov 21, 2012 7:58 AM by 975244

    TextField setting the caret to the end when loosing focus

      Hey everyone,

      I would like to set the caret of a TextField to the end of the text when the TextField loses the focus, so that the last part of the file name will be shwon and not the first part. I´ve tried the following:
      ChangeListener<Boolean> onLooseFocus = new ChangeListener<Boolean>() 
                    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) 
                         if (!newValue.booleanValue()) 
                                      // At this point the caret is at the end and it will show:
                                      //ReadOnlyIntegerProperty [bean: TextField[id=textFieldDateiname, styleClass=text-input text-field], name: caretPosition, value: 76]
      this ChangeListener is added to the focusedProperty() method of my TextField
      It doesn´t work, although the caret is temporarily on the end of the text field.

      Another question: If it works, I would like to reuse the ChangeListener onLooseFocus for diefferent TextField. So I would like to know which TextField lost the focus. I tried
      observable.getSoruce(); // like it works with keyEvent
      System.out.println(observable); // -> ReadOnlyBooleanProperty [bean: TextField[id=textFieldDateiname, styleClass=text-input text-field], name: focused, value: false]
      So the id of the source of the ChangeEvent is known...

      Any ideas?



      Edited by: 972241 on 20.11.2012 06:08
        • 1. Re: TextField setting the caret to the end when loosing focus
          For the latter question, you can cast the Observable to a ReadOnlyProperty, and call getBean() on that; cast the results of the getBean() call to a TextField.

          I have no good solution to the main part of your question. It looks like the default behavior is to revert the carat position to the beginning of the text, and the listener that achieves that is executed after your custom listener.
          So the best hack I can see is to have a flag that overrides the carat position change. Set the flag to true on losing focus. Register a listener with the carat position property, and if the flag is set move the carat back to the end (then unset the flag).
          If you want to use the listeners on multiple text fields, instead of a flag, have a set of textfields which will have their carat positions changes overridden.

          This really is a hack; I'd like to think there's a better solution.
          import java.util.HashSet;
          import java.util.Set;
          import javafx.application.Application;
          import javafx.beans.property.ReadOnlyProperty;
          import javafx.beans.value.ChangeListener;
          import javafx.beans.value.ObservableValue;
          import javafx.event.ActionEvent;
          import javafx.event.EventHandler;
          import javafx.scene.Scene;
          import javafx.scene.control.Button;
          import javafx.scene.control.TextField;
          import javafx.scene.layout.VBox;
          import javafx.stage.Stage;
          public class TestFieldFocusTest extends Application {
            public void start(Stage primaryStage) throws Exception {
              final VBox root = new VBox();
              final TextField tf1 = new TextField();
              final TextField tf2 = new TextField();
              final Set<TextField> overrideNextCaratChange = new HashSet<TextField>();
              final ChangeListener<Boolean> onLoseFocus = new ChangeListener<Boolean>() {
                public void changed(ObservableValue<? extends Boolean> observable,
                    Boolean oldValue, Boolean newValue) {
                  ReadOnlyProperty<? extends Boolean> property = (ReadOnlyProperty<? extends Boolean>) observable ;
                  TextField tf = (TextField) property.getBean() ;
                  if (!newValue.booleanValue()) {
              final ChangeListener<Number> onCaratChange = new ChangeListener<Number>() {
                public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                  ReadOnlyProperty<? extends Number> property = (ReadOnlyProperty<? extends Number>) observable ;
                  TextField tf = (TextField) property.getBean() ;
                  if (overrideNextCaratChange.contains(tf)) {
              Button info = new Button("Show info");
              info.setOnAction(new EventHandler<ActionEvent>() {
                public void handle(ActionEvent arg0) {
                  System.out.printf("Selection: %s (%d characters). Carat position: %d%n",
              root.getChildren().addAll(tf1, tf2, info);
              Scene scene = new Scene(root, 100, 200);
            public static void main(String[] args) {
          • 2. Re: TextField setting the caret to the end when loosing focus
            Hi James,

            thanks a lot! The cast for observable works perfectly!

            The second part works as well, although it is kind of intricate. There should be a way to override the default operation, which sets the caret to the start of the text field...nevertheless, great work!