Класс 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; } }
- См. также:
Краткое описание конструкторов
| Конструктор | Описание |
|---|---|
LineBreakMeasurer |
Создает LineBreakMeasurer для указанного текста. |
LineBreakMeasurer |
Создает LineBreakMeasurer для указанного текста. |
Краткое описание методов
| Модификатор и тип | Метод | Описание |
|---|---|---|
void |
deleteChar |
Обновляет этот LineBreakMeasurer после удаления одного символа из текста и устанавливает текущую позицию в начало абзаца. |
int |
getPosition() |
Возвращает текущую позицию этого LineBreakMeasurer. |
void |
insertChar |
Обновляет этот LineBreakMeasurer после вставки одного символа в текст и устанавливает текущую позицию в начало абзаца. |
TextLayout |
nextLayout |
Возвращает следующий макет и обновляет текущую позицию. |
TextLayout |
nextLayout |
Возвращает следующий макет и обновляет текущую позицию. |
int |
nextOffset |
Возвращает позицию в конце следующего макета. |
int |
nextOffset |
Возвращает позицию в конце следующего макета. |
void |
setPosition |
Задает текущую позицию этого LineBreakMeasurer. |
Методы, объявленные в классе Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait | Модификатор и тип | Метод | Описание |
|---|---|---|
protected Object |
clone() |
Создает и возвращает копию этого объекта. |
boolean |
equals |
Указывает, равен ли этот объект другому объекту. |
protected void |
finalize() |
Устарело, планируется удаление: этот элемент API может быть удален в будущей версии. Метод финализации объявлен устаревшим и планируется к удалению в одном из будущих выпусков. |
final Class |
getClass() |
Возвращает класс времени выполнения этого Object. |
int |
hashCode() |
Возвращает значение хеш-кода этого объекта. |
final void |
notify() |
Пробуждает один поток, ожидающий на мониторе этого объекта. |
final void |
notifyAll() |
Пробуждает все потоки, ожидающие на мониторе этого объекта. |
String |
toString() |
Возвращает строковое представление объекта. |
final void |
wait() |
Приостанавливает текущий поток до тех пор, пока он не будет пробужден, обычно в результате вызова notify или interrupt. |
final void |
wait |
Приостанавливает текущий поток до тех пор, пока он не будет пробужден, обычно в результате вызова notify или interrupt, либо пока не истечет заданный интервал реального времени. |
final void |
wait |
Приостанавливает текущий поток до тех пор, пока он не будет пробужден, обычно в результате вызова notify или interrupt, либо пока не истечет заданный интервал реального времени. |
Подробное описание конструкторов
LineBreakMeasurer
public LineBreakMeasurer(AttributedCharacterIterator text, FontRenderContext frc)
LineBreakMeasurer для указанного текста.- Параметры:
-
text— текст, для которого этотLineBreakMeasurerсоздает объектыTextLayout; текст должен содержать хотя бы один символ; если текст, доступный черезiter, изменится, дальнейшие вызовы этого экземпляраLineBreakMeasurerне определены (за исключением некоторых случаев, когда впоследствии вызываютсяinsertCharилиdeleteChar— см. ниже) -
frc— содержит информацию о графическом устройстве, необходимую для правильного измерения текста; измерения текста могут немного различаться в зависимости от разрешения устройства и таких атрибутов, как сглаживание; этот параметр не задает преобразование междуLineBreakMeasurerи пользовательским пространством - См. также:
LineBreakMeasurer
public LineBreakMeasurer(AttributedCharacterIterator text, BreakIterator breakIter, FontRenderContext frc)
LineBreakMeasurer для указанного текста.- Параметры:
-
text— текст, для которого этотLineBreakMeasurerсоздает объектыTextLayout; текст должен содержать хотя бы один символ; если текст, доступный черезiter, изменится, дальнейшие вызовы этого экземпляраLineBreakMeasurerне определены (за исключением некоторых случаев, когда впоследствии вызываютсяinsertCharилиdeleteChar— см. ниже) -
breakIter—BreakIterator, определяющий разрывы строк -
frc— содержит информацию о графическом устройстве, необходимую для правильного измерения текста; измерения текста могут немного различаться в зависимости от разрешения устройства и таких атрибутов, как сглаживание; этот параметр не задает преобразование междуLineBreakMeasurerи пользовательским пространством - Исключения:
-
IllegalArgumentException— если текст содержит менее одного символа - См. также:
Подробное описание методов
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
public void setPosition(int newPosition)
LineBreakMeasurer.- Параметры:
-
newPosition— текущая позиция этогоLineBreakMeasurer; позиция должна находиться в пределах текста, использованного для создания этогоLineBreakMeasurer(или текста, переданного последним вызовомinsertCharилиdeleteChar - См. также:
insertChar
public void insertChar(AttributedCharacterIterator newParagraph, int insertPos)
LineBreakMeasurer после вставки одного символа в текст и устанавливает текущую позицию в начало абзаца.- Параметры:
-
newParagraph— текст после вставки -
insertPos— позиция в тексте, в которой вставлен символ - Исключения:
-
IndexOutOfBoundsException— еслиinsertPosменьше началаnewParagraphили больше либо равно концуnewParagraph -
NullPointerException— еслиnewParagraphравенnull - См. также:
deleteChar
public void deleteChar(AttributedCharacterIterator newParagraph, int deletePos)
LineBreakMeasurer после удаления одного символа из текста и устанавливает текущую позицию в начало абзаца.- Параметры:
-
newParagraph— текст после удаления -
deletePos— позиция в тексте, в которой удален символ - Исключения:
-
IndexOutOfBoundsException— еслиdeletePosменьше началаnewParagraphили больше концаnewParagraph -
NullPointerException— еслиnewParagraphравенnull - См. также:
© 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.