Класс 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) {
Point2D pen = new Point2D(10, 20);
Graphics2D g2d = (Graphics2D)graphics;
FontRenderContext frc = g2d.getFontRenderContext();
// let styledText be an AttributedCharacterIterator containing at least
// one character
LineBreakMeasurer measurer = new LineBreakMeasurer(styledText, frc);
float wrappingWidth = getSize().width - 15;
while (measurer.getPosition() < fStyledText.length()) {
TextLayout layout = measurer.nextLayout(wrappingWidth);
pen.y += (layout.getAscent());
float dx = layout.isLeftToRight() ?
0 : (wrappingWidth - layout.getAdvance());
layout.draw(graphics, pen.x + dx, pen.y);
pen.y += 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(new Float(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,
BreakIterator breakIter,
FontRenderContext frc) Создаёт |
LineBreakMeasurer(AttributedCharacterIterator text,
FontRenderContext frc) Создаёт |
Методы
| Модификатор и тип | Метод и описание |
|---|---|
void |
deleteChar(AttributedCharacterIterator newParagraph,
int deletePos) Обновляет этот |
int |
getPosition() Возвращает текущую позицию этого |
void |
insertChar(AttributedCharacterIterator newParagraph,
int insertPos) Обновляет этот |
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) Устанавливает текущую позицию этого |
Методы, унаследованные от класса 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, 2020, 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.