Spec-Zone.ru › OpenJDK 25

Класс LineBreakMeasurer

java.lang.Object
java.awt.font.LineBreakMeasurer
public final class LineBreakMeasurer extends Object
Класс LineBreakMeasurer позволяет разбивать форматированный текст на строки (или сегменты), которые помещаются в пределах заданной визуальной ширины. Это полезно для клиентов, которым требуется отображать абзац текста, помещающийся в заданную ширину, называемую шириной переноса.

LineBreakMeasurer создается с помощью итератора по форматированному тексту. Диапазон итератора должен представлять собой один абзац текста. LineBreakMeasurer хранит позицию начала следующего текстового сегмента. Изначально эта позиция совпадает с началом текста. Абзацам назначается общее направление (слева направо или справа налево) согласно правилам двунаправленного форматирования. Все сегменты, полученные из абзаца, имеют то же направление, что и абзац.

Текстовые сегменты получают вызовом метода nextLayout, который возвращает TextLayout, представляющий текст, помещающийся в пределах ширины переноса. Метод nextLayout перемещает текущую позицию в конец макета, возвращенного методом nextLayout.

LineBreakMeasurer реализует наиболее распространенную стратегию разбиения на строки: каждое слово, помещающееся в пределах ширины переноса, размещается в строке. Если первое слово не помещается, в строке размещаются все символы, помещающиеся в пределах ширины переноса. В каждой строке размещается как минимум один символ.

Экземпляры TextLayout, возвращаемые методом LineBreakMeasurer, обрабатывают табуляции как пробелы нулевой ширины. Клиентам, которым нужны сегменты с разделением по табуляциям для позиционирования, следует использовать перегруженный вариант nextLayout, принимающий предельное смещение в тексте. Предельное смещение должно указывать на первый символ после табуляции. Объекты TextLayout, возвращаемые этим методом, заканчиваются на указанном пределе (или раньше, если текст между текущей позицией и пределом не помещается целиком в пределах ширины переноса).

Клиентам, выполняющим компоновку текста с разделением по табуляциям, после размещения первого сегмента в строке нужна немного иная стратегия разбиения на строки. Вместо размещения частей слов в оставшемся пространстве следует целиком переносить на следующую строку слова, которые не помещаются в оставшемся пространстве. Эту стратегию можно запросить с помощью перегруженного варианта nextLayout, принимающего параметр boolean. Если этот параметр равен true, метод nextLayout возвращает null, если первое слово не помещается в заданном пространстве. См. приведенный ниже пример с табуляцией.

Как правило, если текст, использованный для создания LineBreakMeasurer, изменяется, необходимо создать новый LineBreakMeasurer, чтобы учесть это изменение. (Старый LineBreakMeasurer продолжает работать правильно, но не учитывает изменение текста.) Тем не менее, если изменение текста заключается во вставке или удалении одного символа, существующий LineBreakMeasurer можно «обновить», вызвав insertChar или deleteChar. Обновление существующего LineBreakMeasurer выполняется гораздо быстрее, чем создание нового. Клиентам, изменяющим текст на основе пользовательского ввода, следует использовать эти методы.

Примеры:

Отображение абзаца в компоненте

public void paint(Graphics graphics) {

    float dx = 0f, dy = 5f;
    Graphics2D g2d = (Graphics2D)graphics;
    FontRenderContext frc = g2d.getFontRenderContext();

    AttributedString text = new AttributedString(".....");
    AttributedCharacterIterator paragraph = text.getIterator();

    LineBreakMeasurer measurer = new LineBreakMeasurer(paragraph, frc);
    measurer.setPosition(paragraph.getBeginIndex());
    float wrappingWidth = (float)getSize().width;

    while (measurer.getPosition() < paragraph.getEndIndex()) {

        TextLayout layout = measurer.nextLayout(wrappingWidth);

        dy += (layout.getAscent());
        float dx = layout.isLeftToRight() ?
            0 : (wrappingWidth - layout.getAdvance());

        layout.draw(graphics, dx, dy);
        dy += layout.getDescent() + layout.getLeading();
    }
}

Отображение текста с табуляциями. Для простоты предполагается, что общее направление текста — слева направо

public void paint(Graphics graphics) {

    float leftMargin = 10, rightMargin = 310;
    float[] tabStops = { 100, 250 };

    // assume styledText is an AttributedCharacterIterator, and the number
    // of tabs in styledText is tabCount

    int[] tabLocations = new int[tabCount+1];

    int i = 0;
    for (char c = styledText.first(); c != styledText.DONE; c = styledText.next()) {
        if (c == '\t') {
            tabLocations[i++] = styledText.getIndex();
        }
    }
    tabLocations[tabCount] = styledText.getEndIndex() - 1;

    // Now tabLocations has an entry for every tab's offset in
    // the text.  For convenience, the last entry is tabLocations
    // is the offset of the last character in the text.

    LineBreakMeasurer measurer = new LineBreakMeasurer(styledText);
    int currentTab = 0;
    float verticalPos = 20;

    while (measurer.getPosition() < styledText.getEndIndex()) {

        // Lay out and draw each line.  All segments on a line
        // must be computed before any drawing can occur, since
        // we must know the largest ascent on the line.
        // TextLayouts are computed and stored in a Vector;
        // their horizontal positions are stored in a parallel
        // Vector.

        // lineContainsText is true after first segment is drawn
        boolean lineContainsText = false;
        boolean lineComplete = false;
        float maxAscent = 0, maxDescent = 0;
        float horizontalPos = leftMargin;
        Vector layouts = new Vector(1);
        Vector penPositions = new Vector(1);

        while (!lineComplete) {
            float wrappingWidth = rightMargin - horizontalPos;
            TextLayout layout =
                    measurer.nextLayout(wrappingWidth,
                                        tabLocations[currentTab]+1,
                                        lineContainsText);

            // layout can be null if lineContainsText is true
            if (layout != null) {
                layouts.addElement(layout);
                penPositions.addElement(Float.valueOf(horizontalPos));
                horizontalPos += layout.getAdvance();
                maxAscent = Math.max(maxAscent, layout.getAscent());
                maxDescent = Math.max(maxDescent,
                    layout.getDescent() + layout.getLeading());
            } else {
                lineComplete = true;
            }

            lineContainsText = true;

            if (measurer.getPosition() == tabLocations[currentTab]+1) {
                currentTab++;
            }

            if (measurer.getPosition() == styledText.getEndIndex())
                lineComplete = true;
            else if (horizontalPos >= tabStops[tabStops.length-1])
                lineComplete = true;

            if (!lineComplete) {
                // move to next tab stop
                int j;
                for (j=0; horizontalPos >= tabStops[j]; j++) {}
                horizontalPos = tabStops[j];
            }
        }

        verticalPos += maxAscent;

        Enumeration layoutEnum = layouts.elements();
        Enumeration positionEnum = penPositions.elements();

        // now iterate through layouts and draw them
        while (layoutEnum.hasMoreElements()) {
            TextLayout nextLayout = (TextLayout) layoutEnum.nextElement();
            Float nextPosition = (Float) positionEnum.nextElement();
            nextLayout.draw(graphics, nextPosition.floatValue(), verticalPos);
        }

        verticalPos += maxDescent;
    }
}
См. также:
  • TextLayout

Краткое описание конструкторов

Конструктор Описание
LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc)
Создает LineBreakMeasurer для указанного текста.
LineBreakMeasurer(AttributedCharacterIterator text, BreakIterator breakIter, FontRenderContext frc)
Создает LineBreakMeasurer для указанного текста.

Краткое описание методов

Модификатор и тип Метод Описание
void deleteChar(AttributedCharacterIterator newParagraph, int deletePos)
Обновляет этот LineBreakMeasurer после удаления из текста одного символа и устанавливает текущую позицию в начало абзаца.
int getPosition()
Возвращает текущую позицию этого LineBreakMeasurer.
void insertChar(AttributedCharacterIterator newParagraph, int insertPos)
Обновляет этот LineBreakMeasurer после вставки в текст одного символа и устанавливает текущую позицию в начало абзаца.
TextLayout nextLayout(float wrappingWidth)
Возвращает следующий макет и обновляет текущую позицию.
TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord)
Возвращает следующий макет и обновляет текущую позицию.
int nextOffset(float wrappingWidth)
Возвращает позицию в конце следующего макета.
int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord)
Возвращает позицию в конце следующего макета.
void setPosition(int newPosition)
Устанавливает текущую позицию этого LineBreakMeasurer.

Методы, объявленные в классе Object

clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Подробное описание конструкторов

LineBreakMeasurer

public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc)
Создает LineBreakMeasurer для указанного текста.
Параметры:
text — текст, для которого этот LineBreakMeasurer создает объекты TextLayout; текст должен содержать хотя бы один символ; если текст, доступный через iter, изменится, дальнейшие вызовы этого экземпляра LineBreakMeasurer не определены (за исключением некоторых случаев, когда впоследствии вызываются insertChar или deleteChar — см. ниже)
frc — содержит сведения о графическом устройстве, необходимые для правильного измерения текста; измерения текста могут немного различаться в зависимости от разрешения устройства и таких атрибутов, как сглаживание; этот параметр не задает преобразование между LineBreakMeasurer и пользовательским пространством
См. также:
  • insertChar(AttributedCharacterIterator, int)
  • deleteChar(AttributedCharacterIterator, int)

LineBreakMeasurer

public LineBreakMeasurer(AttributedCharacterIterator text, BreakIterator breakIter, FontRenderContext frc)
Создает LineBreakMeasurer для указанного текста.
Параметры:
text — текст, для которого этот LineBreakMeasurer создает объекты TextLayout; текст должен содержать хотя бы один символ; если текст, доступный через iter, изменится, дальнейшие вызовы этого экземпляра LineBreakMeasurer не определены (за исключением некоторых случаев, когда впоследствии вызываются insertChar или deleteChar — см. ниже)
breakIter — BreakIterator, задающий места разрывов строк
frc — содержит сведения о графическом устройстве, необходимые для правильного измерения текста; измерения текста могут немного различаться в зависимости от разрешения устройства и таких атрибутов, как сглаживание; этот параметр не задает преобразование между LineBreakMeasurer и пользовательским пространством
Исключения:
IllegalArgumentException — если текст содержит менее одного символа
См. также:
  • insertChar(AttributedCharacterIterator, int)
  • deleteChar(AttributedCharacterIterator, int)

Подробное описание методов

nextOffset

public int nextOffset(float wrappingWidth)
Возвращает позицию в конце следующего макета. НЕ обновляет текущую позицию этого LineBreakMeasurer.
Параметры:
wrappingWidth — максимальная видимая ширина текста в следующем макете
Возвращает:
смещение в тексте, обозначающее предел следующего TextLayout.

nextOffset

public int nextOffset(float wrappingWidth, int offsetLimit, boolean requireNextWord)
Возвращает позицию в конце следующего макета. НЕ обновляет текущую позицию этого LineBreakMeasurer.
Параметры:
wrappingWidth — максимальная видимая ширина текста в следующем макете
offsetLimit — первый символ, который нельзя включить в следующий макет, даже если текст после предела поместится в пределах ширины переноса; offsetLimit должно быть больше текущей позиции
requireNextWord — если true, возвращается текущая позиция, если следующее слово целиком не помещается в wrappingWidth; если false, возвращаемое смещение как минимум на единицу больше текущей позиции
Возвращает:
смещение в тексте, обозначающее предел следующего TextLayout

nextLayout

public TextLayout nextLayout(float wrappingWidth)
Возвращает следующий макет и обновляет текущую позицию.
Параметры:
wrappingWidth — максимальная видимая ширина текста в следующем макете
Возвращает:
TextLayout, начинающийся с текущей позиции и представляющий следующую строку, помещающуюся в wrappingWidth

nextLayout

public TextLayout nextLayout(float wrappingWidth, int offsetLimit, boolean requireNextWord)
Возвращает следующий макет и обновляет текущую позицию.
Параметры:
wrappingWidth — максимальная видимая ширина текста в следующем макете
offsetLimit — первый символ, который нельзя включить в следующий макет, даже если текст после предела поместится в пределах ширины переноса; offsetLimit должно быть больше текущей позиции
requireNextWord — если true и слово целиком в текущей позиции не помещается в пределах ширины переноса, возвращается null. Если false, возвращается допустимый макет, включающий как минимум символ в текущей позиции
Возвращает:
TextLayout, начинающийся с текущей позиции и представляющий следующую строку, помещающуюся в wrappingWidth. Если текущая позиция находится в конце текста, использованного этим LineBreakMeasurer, возвращается null

getPosition

public int getPosition()
Возвращает текущую позицию этого LineBreakMeasurer.
Возвращает:
текущую позицию этого LineBreakMeasurer
См. также:
  • setPosition(int)

setPosition

public void setPosition(int newPosition)
Устанавливает текущую позицию этого LineBreakMeasurer.
Параметры:
newPosition — текущая позиция этого LineBreakMeasurer; позиция должна находиться в пределах текста, использованного для создания этого LineBreakMeasurer (или в тексте, который последним передавался в insertChar или deleteChar
См. также:
  • getPosition()

insertChar

public void insertChar(AttributedCharacterIterator newParagraph, int insertPos)
Обновляет этот LineBreakMeasurer после вставки в текст одного символа и устанавливает текущую позицию в начало абзаца.
Параметры:
newParagraph — текст после вставки
insertPos — позиция в тексте, в которую вставляется символ
Исключения:
IndexOutOfBoundsException — если insertPos меньше начала newParagraph или больше либо равно концу newParagraph
NullPointerException — если newParagraph равно null
См. также:
  • deleteChar(AttributedCharacterIterator, int)

deleteChar

public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos)
Обновляет этот LineBreakMeasurer после удаления из текста одного символа и устанавливает текущую позицию в начало абзаца.
Параметры:
newParagraph — текст после удаления
deletePos — позиция в тексте, из которой удаляется символ
Исключения:
IndexOutOfBoundsException — если deletePos меньше начала newParagraph или больше конца newParagraph
NullPointerException — если newParagraph равно null
См. также:
  • insertChar(AttributedCharacterIterator, int)

Сообщить об ошибке или предложить улучшение
Дополнительную справочную информацию по API и документацию для разработчиков см. в документации Java SE, содержащей более подробные описания для разработчиков, концептуальные обзоры, определения терминов, обходные решения и примеры работающего кода. Другие версии.
Java является товарным знаком или зарегистрированным товарным знаком Oracle и/или ее аффилированных лиц в США и других странах.
Авторские права © 1993, 2025, Oracle и/или ее аффилированные лица, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
Все права защищены. Использование регулируется условиями лицензии и политикой распространения документации.

© 1993, 2025, Oracle and/or its affiliates. All rights reserved.
Documentation extracted from Debian's OpenJDK Development Kit package.
Licensed under the GNU General Public License, version 2, with the Classpath Exception.
Various third party code in OpenJDK is licensed under different licenses (see Debian package).
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
https://docs.oracle.com/en/java/javase/25/docs/api/java.desktop/java/awt/font/LineBreakMeasurer.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API