Skip to content

8314482: TextFlow: TabStopPolicy #1744

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 55 commits into
base: master
Choose a base branch
from

Conversation

andy-goryachev-oracle
Copy link
Contributor

@andy-goryachev-oracle andy-goryachev-oracle commented Mar 26, 2025

Tab Stop Policy

Andy Goryachev

andy.goryachev@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

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
     *
     * @since 14
     */
    public final IntegerProperty tabSizeProperty() {

TabStopPolicy

/**
 * The TabStopPolicy determines the tab stop positions within the text layout.
 *
 * @since 999 TODO
 */
public class TabStopPolicy {
    /**
     * Constructs a new {@code TabStopPolicy} instance.
     */
    public TabStopPolicy() {

    /**
     * Specifies the unmodifiable list of tab stops, sorted by position from smallest to largest.
     * The list can be changed using
     *
     * @return the non-null, unmodifiable list of tab stops, sorted by position
     */
    public final ObservableList<TabStop> tabStops() {

    /**
     * Provides default tab stops (beyond the last tab stop specified by {@code #tabStops()},
     * as a fixed repeating distance in pixels from the last tab stop position.
     * The position of default tab stops is computed at regular intervals relative to
     * the leading edge of the {@code TextFlow} this policy is registered with.
     * <p>
     * The value of less than or equal 0 disables the default stops.
     *
     * @return the default tab stops property
     * @defaultValue 0
     */
    public final DoubleProperty defaultStopsProperty() {

    public final double getDefaultStops() {

    public final void setDefaultStops(double value) {

TabStop

/**
 * This class encapsulates an immutable single tab stop within the {@link TabStopPolicy}.
 * <p>
 * A tab stop is at a specified distance from the
 * left margin, aligns text in a specified way, and has a specified leader.
 *
 * @since 999 TODO
 */
public class TabStop {
    /**
     * Constructs a new tab stop with the specified position.
     *
     * @param position the position in pixels
     */
    public TabStop(double position) {

    /**
     * Returns the position, in pixels, of the tab.
     * @return the position of the tab
     */
    public final double getPosition() {

Alternatives

None known.

Risks and Assumptions

Possible incompatibility with custom controls which extend TextFlow and declare a property with the same name.

Dependencies

None.

References

  1. JDK-8314482
  2. https://github.com/andy-goryachev-oracle/Test/blob/main/doc/TabStopPolicy/TabStopPolicy.md

Progress

  • Change requires a CSR request matching fixVersion jfx25 to be approved (needs to be created)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed (2 reviews required, with at least 1 Reviewer, 1 Author)

Issue

  • JDK-8314482: TextFlow: TabStopPolicy (Enhancement - P3)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1744/head:pull/1744
$ git checkout pull/1744

Update a local copy of the PR:
$ git checkout pull/1744
$ git pull https://git.openjdk.org/jfx.git pull/1744/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 1744

View PR using the GUI difftool:
$ git pr show -t 1744

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1744.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper
Copy link

bridgekeeper bot commented Mar 26, 2025

👋 Welcome back angorya! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Mar 26, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@andy-goryachev-oracle
Copy link
Contributor Author

/csr
/reviewers 2

@openjdk openjdk bot added the csr Need approved CSR to integrate pull request label May 19, 2025
@openjdk
Copy link

openjdk bot commented May 19, 2025

@andy-goryachev-oracle has indicated that a compatibility and specification (CSR) request is needed for this pull request.

@andy-goryachev-oracle please create a CSR request for issue JDK-8314482 with the correct fix version. This pull request cannot be integrated until the CSR request is approved.

@openjdk
Copy link

openjdk bot commented May 19, 2025

@andy-goryachev-oracle
The total number of required reviews for this PR (including the jcheck configuration and the last /reviewers command) is now set to 2 (with at least 1 Reviewer, 1 Author).

@andy-goryachev-oracle andy-goryachev-oracle marked this pull request as ready for review May 19, 2025 22:10
@openjdk openjdk bot added the rfr Ready for review label May 19, 2025
@mlbridge
Copy link

mlbridge bot commented May 19, 2025

Webrevs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
csr Need approved CSR to integrate pull request rfr Ready for review
Development

Successfully merging this pull request may close these issues.

1 participant