RFR: 8314482: TextFlow: TabStopPolicy [v3]

Kevin Rushforth kcr at openjdk.org
Wed Jun 18 17:24:38 UTC 2025


On Wed, 18 Jun 2025 15:34:15 GMT, Andy Goryachev <angorya at openjdk.org> wrote:

>> # Tab Stop Policy
>> 
>> Andy Goryachev
>> 
>> <andy.goryachev at oracle.com>
>> 
>> 
>> ## Summary
>> 
>> Introduce a `tabStopPolicy` property in the `TextFlow` class which, when set, overrides the existing `tabSize`
>> value and provides consistent way of setting tab stops at the paragraph level, regardless of the individual text
>> segments font [0].
>> 
>> ![Screenshot 2025-05-19 at 15 03 26](https://github.com/user-attachments/assets/32f2474d-7d2b-47b0-a22c-410d485f4e40)
>> 
>> 
>> ## Goals
>> 
>> The goal of this proposal is to provide a better way for controlling tab stops in the `TextFlow` containing rich text.
>> 
>> 
>> 
>> ## Non-Goals
>> 
>> The following are not the goals of this proposal:
>> 
>> - support for tab stop types (BAR, or DECIMAL), or attributes like `alignment`
>> - support the `leader` property (symbols to fill the empty space before the tab stop)
>> - support for `firstLineIndent` property
>> - deprecate the `TextFlow::tabsize` property
>> 
>> 
>> 
>> ## Motivation
>> 
>> The existing `tabSize` property in the `TextFlow` is inadequate for representing tab stops when the content
>> contains text with different font sizes.
>> 
>> In addition to that, a rich text editor might require support for user-customizable tab stops, similar to that provided
>> in RTF or MS Word documents.
>> 
>> 
>> 
>> 
>> ## Description
>> 
>> ### TextFlow
>> 
>> 
>>     /**
>>      * {@code TabAdvancePolicy} determines the tab stop positions within this {@code TextFlow}.
>>      * <p>
>>      * A non-null {@code TabAdvancePolicy} overrides values set by {@link #setTabSize(int)},
>>      * as well as any values set by {@link Text#setTabSize(int)} in individual {@code Text} instances within
>>      * this {@code TextFlow}.
>>      *
>>      * @defaultValue null
>>      *
>>      * @since 999 TODO
>>      */
>>     public final ObjectProperty<TabStopPolicy> tabStopPolicyProperty() {
>> 
>>     public final TabStopPolicy getTabStopPolicy() {
>> 
>>     public final void setTabStopPolicy(TabStopPolicy policy) {
>> 
>>     /**
>>      * The size of a tab stop in spaces.
>>      * Values less than 1 are treated as 1. This value overrides the
>>      * {@code tabSize} of contained {@link Text} nodes.
>>      * <p>
>> +     * Note that this method should not be used to control the tab placement when multiple {@code Text} nodes
>> +     * with different fonts are contained within this {@code TextFlow}.
>> +     * In this case, the {@link #setTabStopPolicy(TabStopPolicy)} should be used instead.
>>      *
>>      * @defaultValue 8
>>      *...
>
> Andy Goryachev has updated the pull request incrementally with one additional commit since the last revision:
> 
>   review comments

More API comments.

modules/javafx.graphics/src/main/java/javafx/scene/text/TabStop.java line 31:

> 29:  * <p>
> 30:  * A tab stop is at a specified distance from the
> 31:  * left margin, aligns text in a specified way, and has a specified leader.

Where is the alignment and leader specified?

modules/javafx.graphics/src/main/java/javafx/scene/text/TabStop.java line 33:

> 31:  * left margin, aligns text in a specified way, and has a specified leader.
> 32:  *
> 33:  * @since 999 TODO

Change this to either 25 (if you'd like to shoot for getting it into 25) or 26.

modules/javafx.graphics/src/main/java/javafx/scene/text/TabStopPolicy.java line 44:

> 42: 
> 43:     /**
> 44:      * Constructs a new {@code TabStopPolicy} instance.

Minor: Maybe add "with an empty list of stops"?

modules/javafx.graphics/src/main/java/javafx/scene/text/TabStopPolicy.java line 53:

> 51:      *
> 52:      * @return the non-null, list of tab stops
> 53:      */

Minor: remove the comma.

modules/javafx.graphics/src/main/java/javafx/scene/text/TabStopPolicy.java line 60:

> 58:     /**
> 59:      * Provides default tab stops (beyond the last tab stop specified by {@code #tabStops()},
> 60:      * as a fixed repeating distance in pixels from the last tab stop position.

This is a little misleading. The stops are applied after the last tap stop position, but the distance is not fixed "from" that point. The next sentence explains this, but since the first sentence shows up in the method summary, I might reword this a bit to remove the possibility of this misunderstanding.

How about: "as a fixed repeating distance in pixels for tabs after the last tab stop position." or similar?

modules/javafx.graphics/src/main/java/javafx/scene/text/TabStopPolicy.java line 64:

> 62:      * the leading edge of the {@code TextFlow} this policy is registered with.
> 63:      * <p>
> 64:      * The value of less than or equal 0 disables the default stops.

Minor: "A value less than or equal ..."

modules/javafx.graphics/src/main/java/javafx/scene/text/TabStopPolicy.java line 67:

> 65:      *
> 66:      * @return the default tab stops property
> 67:      * @defaultValue 0

Would "8" be a better default value? I think having tabs do something (instead of effectively being ignored) by default when you create a TabStopPolicy would be less surprising to app developers.

-------------

PR Review: https://git.openjdk.org/jfx/pull/1744#pullrequestreview-2940041342
PR Review Comment: https://git.openjdk.org/jfx/pull/1744#discussion_r2155112258
PR Review Comment: https://git.openjdk.org/jfx/pull/1744#discussion_r2155138326
PR Review Comment: https://git.openjdk.org/jfx/pull/1744#discussion_r2155120637
PR Review Comment: https://git.openjdk.org/jfx/pull/1744#discussion_r2155128701
PR Review Comment: https://git.openjdk.org/jfx/pull/1744#discussion_r2155108697
PR Review Comment: https://git.openjdk.org/jfx/pull/1744#discussion_r2155114912
PR Review Comment: https://git.openjdk.org/jfx/pull/1744#discussion_r2155133015


More information about the openjfx-dev mailing list