Spec-Zone.ru › OpenJDK 24

Класс LineBreakMeasurer

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

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

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

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

Экземпляры TextLayout, возвращаемые методом LineBreakMeasurer, обрабатывают табуляции как пробелы шириной 0. Клиенты, которые хотят получить сегменты, ограниченные табуляцией, для позиционирования, должны использовать перегрузку метода 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.

Методы, унаследованные от класса java.lang.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(java.text.AttributedCharacterIterator, int)
  • deleteChar(java.text.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(java.text.AttributedCharacterIterator, int)
  • deleteChar(java.text.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(java.text.AttributedCharacterIterator, int)

deleteChar

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

© 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://download.java.net/java/early_access/jdk24/docs/api/java.desktop/java/awt/font/LineBreakMeasurer.html

Spec-Zone.ru

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