2
votes

I have created a new JavaFX component to be used for Braille input by extending the TextArea component. Unfortunately, the default word wrap behavior of a TextArea component will break to a new line right in the middle of several braille characters rather than breaking only at the spaces between words. I have tried searching for the methods that define the word wrap behavior in the TextArea component so I could override them, but I have not been able to find those methods.

How can I override this word wrap behavior so that line breaks will only be inserted at spaces?

1

1 Answers

0
votes

I've had a play around with the default behaviour of a JavaFX TextArea. I used both the standard latin alphabet as well as Unicode characters. Both behaved the same.

With text wrap enabled, the default policy seems to be to break at the first space before the width of the area is exceeded. If a single "word" (any consecutive sequence of characters) is too long to fit within the width of the container, it will start on a newline, break at the width of the container and carry on to the next line. This is exactly what I would expect in this situation. You've told it you want to enforce text wrapping and if a word doesn't fit on a line, there's not a great deal it can do.

Anyway, a TextArea has a property wrapText which allows us to control whether this text wrapping will be added or not. Looking at where this value is used in the source code may give us some insight into how its used.

 private static final CssMetaData<TextArea,Boolean> WRAP_TEXT =
      new CssMetaData<TextArea,Boolean>("-fx-wrap-text",
          StyleConverter.getBooleanConverter(), false) {

      @Override
      public boolean isSettable(TextArea n) {
          return !n.wrapText.isBound();
      }

      @Override
      public StyleableProperty<Boolean> getStyleableProperty(TextArea n) {
          return (StyleableProperty<Boolean>)(WritableValue<Boolean>)n.wrapTextProperty();
      }
 };

Effectively what's happening here is that this boolean property is being bound to a CSS property -fx-wrap-text. This CSS property only takes a boolean argument - text wrap is either on or off, there are no alternative modes. We can then presume that CSS property is being used by the renderer to enforce the text wrap policy. This is way too low-level to bother about overriding.

To solve your problem, I would turn text wrap off and set up a listener to the textProperty() of your TextArea. When the text changes, insert newlines yourself at whatever places you deem appropriate.