9 Replies Latest reply: Nov 26, 2012 12:23 PM by edward17 RSS

    Text Highlighting behavior on lost focus

    edward17
      One of my users reported the issue that selected text does NOT lose highlighting when the control the text is in (TextField, TextArea) loses focus.

      My question - should it?

      is this a bug?

      Is there a workaround?
        • 1. Re: Text Highlighting behavior on lost focus
          dscarminiabielefeld
          I've a Stage with a textfield and a text on it. When I get focus on the Textfield, it highlights the text and itself. when i lose the focus and click on something else in the same stage, or a different one, it loses the highlighting. This is how it should be. So if this doesn't work the same way for you, there is something wrong i guess.
          Greetings.

          Edited by: dscarminiabielefeld on 19-Nov-2012 23:40
          • 2. Re: Text Highlighting behavior on lost focus
            edward17
            Is the behavior the same when you explicitly select the text?
            • 3. Re: Text Highlighting behavior on lost focus
              dscarminiabielefeld
              Hi,

              when I highlight the text, and click on an other stage, it loses all highlighting. when i click on the stage with the textfield again, it automatically gets back the highlighting.
              • 4. Re: Text Highlighting behavior on lost focus
                edward17
                OK, in the very simple code example there are two TextAreas.

                I put text in one, put text in the other
                Then I highlight the text in the first
                click outside the box - expect to lose highlighting
                highlighing text in second box, expect to lose highlighting

                I end up with text hightlighted in both boxes. You have to click a second time IN THE SAME BOX to remove hightlighting for that box
                <?xml version="1.0" encoding="UTF-8"?>
                
                <?import java.lang.*?>
                <?import java.util.*?>
                <?import javafx.scene.*?>
                <?import javafx.scene.control.*?>
                <?import javafx.scene.layout.*?>
                
                <AnchorPane id="AnchorPane" prefHeight="344.0" prefWidth="433.0" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication5.SampleController">
                  <children>
                    <TextArea layoutX="160.0" layoutY="180.0" prefWidth="200.0" wrapText="true" />
                    <TextArea layoutX="14.0" layoutY="14.0" prefWidth="200.0" wrapText="true" />
                  </children>
                </AnchorPane>
                package javafxapplication5;
                
                import java.net.URL;
                import java.util.ResourceBundle;
                import javafx.fxml.Initializable;
                
                public class SampleController implements Initializable {
                
                    @Override
                    public void initialize(URL url, ResourceBundle rb) {
                        // TODO
                    }
                }
                • 5. Re: Text Highlighting behavior on lost focus
                  dscarminiabielefeld
                  Yes, it's the same for me, so i guess the default property is that you only lose the highlighting, if you click in your TA again, which does make sense in my opinion, because if you try to copy something, you often don't want to lose the focus on your highlited words too easy. if you don't want this effect, you have to implement it. Can't tell at the moment how. So the question is:
                  Is there a function, that returns a value, if you lose the focus of your textarea, and if yes, is there a second function that un-highlight a specific text? found none.
                  Regards
                  • 6. Re: Text Highlighting behavior on lost focus
                    James_D
                    I agree: I think this is the intentional default behavior.

                    To override it, listen for changes in the focusedProperty and deselect the text when focus is lost:
                    <?xml version="1.0" encoding="UTF-8"?>
                     
                    <?import java.lang.*?>
                    <?import java.util.*?>
                    <?import javafx.scene.*?>
                    <?import javafx.scene.control.*?>
                    <?import javafx.scene.layout.*?>
                     
                    <AnchorPane id="AnchorPane" prefHeight="344.0" prefWidth="433.0" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication5.SampleController">
                      <children>
                        <TextArea layoutX="160.0" layoutY="180.0" prefWidth="200.0" wrapText="true" fx:id="textArea1" />
                        <TextArea layoutX="14.0" layoutY="14.0" prefWidth="200.0" wrapText="true" fx:id="textArea2" />
                      </children>
                    </AnchorPane>
                    package javafxapplication5;
                     
                    import java.net.URL;
                    import java.util.ResourceBundle;
                    import javafx.fxml.Initializable;
                     
                    public class SampleController implements Initializable {
                       @FXML private TextArea textArea1 ;
                       @FXML private TextArea textArea2 ;
                    
                        @Override
                        public void initialize(URL url, ResourceBundle rb) {
                        final ChangeListener<Boolean> deselectOnLoseFocus = new ChangeListener<Boolean>() {
                          @Override
                          public void changed(ObservableValue<? extends Boolean> observable,
                              Boolean oldValue, Boolean newValue) {
                            if (oldValue && ! newValue) {
                              ReadOnlyProperty<? extends Boolean> property = (ReadOnlyProperty<? extends Boolean>) observable ;
                              TextArea textArea = (TextArea) property.getBean() ;
                              int caretPos = textArea.getCaretPosition();
                              textArea.selectRange(caretPos, caretPos);
                            }
                          }
                        };
                        textArea1.focusedProperty().addListener(deselectOnLoseFocus);
                        textArea2.focusedProperty().addListener(deselectOnLoseFocus);        
                        }
                    }
                    • 7. Re: Text Highlighting behavior on lost focus
                      jsmith
                      Minor optimization - there is an explicit deselect function (http://docs.oracle.com/javafx/2/api/javafx/scene/control/TextInputControl.html#deselect%28%29), so for James code you can use:
                      textArea.deselect();
                      Instead of:
                      int caretPos = textArea.getCaretPosition();
                      textArea.selectRange(caretPos, caretPos);
                      • 8. Re: Text Highlighting behavior on lost focus
                        James_D
                        Thanks jsmith for the code improvement.

                        I've revised my opinion and now think there may be a bug here.

                        I was thinking that a better solution would be to maintain the selected state of the text, but to change its appearance when the text area loses focus; for example to highlight it in gray when not focused but in blue when focused.

                        I tried this with css (and removed the listeners from my previous post):
                        .text-area {
                             -fx-highlight-fill: gray ;
                        }
                        
                        .text-area:focused {
                             -fx-highlight-fill: dodgerblue ;
                        }
                        The selected text is always highlighted in blue, regardless of the focused state. The css is being read (try changing dodgerblue to another color), but it never picks up the unfocused state.

                        I also tried this with explicit listeners. Instead of the initialize method in the previous code, try this:
                          public void initialize() {
                            final ChangeListener<Boolean> changeHighlightOnFocusChange = new ChangeListener<Boolean>() {
                              @Override
                              public void changed(ObservableValue<? extends Boolean> observable,
                                  Boolean oldValue, Boolean newValue) {
                                
                                  ReadOnlyProperty<? extends Boolean> property = (ReadOnlyProperty<? extends Boolean>) observable ;
                                  TextArea textArea = (TextArea) property.getBean() ;
                                  String highlightColor ;
                                  if (newValue) {
                                    highlightColor = "dodgerblue" ;
                                  } else {
                                    highlightColor = "gray" ;
                                  }
                                  String style = "-fx-highlight-fill: "+highlightColor+" ;" ;
                                  textArea.setStyle(style);
                              }
                            };
                            textArea1.focusedProperty().addListener(changeHighlightOnFocusChange);
                            textArea2.focusedProperty().addListener(changeHighlightOnFocusChange);
                          }
                        The behavior is the same: selected text is always highlighted in blue, even after losing focus. Again, change dodgerblue to some other color and you will see that the listeners are being invoked.
                        • 9. Re: Text Highlighting behavior on lost focus
                          edward17
                          I can live with expected Default behavior.