|
Spec-Zone .ru
спецификации, руководства, описания, API
|
Этот раздел обсуждает, как работать с двунаправленным текстом с классами в java.awt и пакеты. Эти классы, которым позволяют Вы потянуть разработанный текст на любом языке или сценарий, поддерживаемый Стандартом Unicode: глобальная система кодировки символов для того, чтобы обработать разнообразные современные, классические, и исторические языки. При рисовании текста направление, текст читается, должно быть принято во внимание так, чтобы все слова в строке вывели на экран правильно. Эти классы поддерживают направление текста, и правильно тянет это независимо от того, если строка работает слева направо, справа налево, или оба (двунаправленные). Двунаправленный текст представляет интересные проблемы для того, чтобы правильно расположить каре, точно определяя местоположение выборов, и правильно выводя на экран многократные строки. Также двунаправленный и справа налево текст представляют подобные проблемы для того, чтобы переместить каре в корректное направление в ответ на правые и левые нажатия клавиши со стрелкой.
Следующие темы затрагиваются:
Если Вы планируете работать с компонентами Swing, см.
SE Java хранит текст в памяти в логическом порядке, который является порядком, в котором символы и слова читаются и пишутся. Логический порядок является не обязательно тем же самым как визуальным порядком, который является порядком, в котором выводятся на экран соответствующие глифы.
Система письменности' визуальный порядок должна сохраняться в двунаправленном тексте, даже когда языки смешиваются вместе. Это иллюстрируется в следующем числе, которое выводит на экран арабскую фразу, встроенную в английское предложение.
Отметьте: В этом и последующих примерах, арабский и еврейский текст представляется прописными буквами, и пробелы представляются подчеркиваниями. Каждая иллюстрация содержит две части: представление символов, сохраненных в памяти (символы в логическом порядке) сопровождаемый представлением того, как те символы выводятся на экран (символы в визуальном порядке). Числа ниже символьных полей указывают на смещения вставки.

Даже при том, что они - часть английского предложения, арабские слова выводятся на экран в арабском порядке сценария, справа налево. Поскольку курсивное арабское слово логически после арабского языка в простом тексте это визуально налево от простого текста.
Когда строка со смесью слева направо и справа налево текст выводится на экран, основное направление существенное. Основное направление является порядком сценария преобладающей системы письменности. Например, если текст является прежде всего английским с некоторым встроенным арабским языком, то основное направление слева направо. Если текст является прежде всего арабским с некоторым встроенным английским языком или числами, то основное направление справа налево.
Основное направление определяет порядок, в котором выводятся на экран сегменты текста с общим направлением. В примере, показанном в предыдущем числе, основное направление слева направо. В этом примере есть три направленных выполнения: английский текст в начале предложения работает слева направо, арабские текстовые выполнения справа налево, и выполнения периода слева направо.
Графика часто встраивается в поток текста. Эта встроенная графика ведет себя как глифы с точки зрения того, как они влияют на текстовый поток и обертывание строки. Такая встроенная графическая потребность, которая будет расположена, используя тот же самый двунаправленный алгоритм компоновки так, чтобы они появились в надлежащем расположении в потоке символов.
SE Java использует Unicode Двунаправленный Алгоритм, который является алгоритмом, который используется, чтобы упорядочить глифов в пределах строки, таким образом определяя направленность двунаправленных текстов. В большинстве случаев Вы не должны включать дополнительную информацию для этого алгоритма, чтобы получить корректное упорядочивание дисплея.
Чтобы позволить пользователю редактировать двунаправленный текст, следует быть в состоянии сделать следующее:
В доступном для редактирования тексте каре используется, чтобы графически представить текущую точку вставки, позицию в тексте, где новые символы будут вставлены. Как правило, каре показывают как мигающая вертикальная панель между двумя глифами. Новые символы вставляются и выводятся на экран в расположении каре.
Вычисление позиции каре может быть усложнено, особенно для двунаправленного текста. У смещений вставки на направленных границах есть две возможных позиции каре, потому что два глифа, которые соответствуют символьному смещению, не выводятся на экран смежные с друг другом. Это иллюстрируется в следующем числе. В этом числе каре, как показывают, как квадратные скобки указывают на глифа, которому соответствует каре.

Символ смещал 8, соответствует расположению после подчеркивания и перед A. Если пользователь вводит арабский символ, его глиф выводится на экран направо от (перед) A; если пользователь вводит английский символ, его глиф выводится на экран направо от (после) подчеркивания.
Чтобы обработать эту ситуацию, некоторые системы выводят на экран двойные каре, strong (основное) каре и слабое (вторичное) каре. Каре strong указывает, где вставленный символ будет выведен на экран, когда направление того символа будет тем же самым как основным направлением текста. Слабое каре показывает, где вставленный символ будет выведен на экран, когда направление символа будет противоположностью основного направления автоматически поддерживает двойные каре.
Когда Вы работаете с двунаправленным текстом, невозможно просто добавить ширины глифов перед символьным смещением, чтобы вычислить позицию каре. Если бы Вы сделали, то каре было бы оттянуто в неправильном месте, как показано в следующем числе:

Для каре, которое будет должным образом расположено, ширины глифов налево от смещения должны быть добавлены и текущий принятый во внимание контекст. Если контекст не будет принят во внимание, метрики глифа будут не обязательно соответствовать дисплей. (Контекст может влиять, какие глифы используются.)
Все текстовые редакторы позволяют пользователю перемещать каре с клавишами со стрелками. Пользователи ожидают, что каре переместится в направлении нажатой клавиши со стрелкой. В слева направо тексте, перемещая смещение вставки просто: клавиша со стрелкой вправо увеличивает вставку, смещенную одним, и клавиша со стрелкой влево уменьшает это одним. В двунаправленном тексте или в тексте с лигатурами, это поведение заставило бы каре переходить через глифов на границах направления и перемещаться в обратное направление в пределах различных направленных выполнений.
Чтобы переместить каре гладко через двунаправленный текст, Вы должны принять во внимание направление текстовых выполнений. Невозможно просто постепенно увеличить смещение вставки, когда клавиша со стрелкой вправо нажимается, и постепенно уменьшите это, когда клавиша со стрелкой влево нажимается. Если текущее смещение вставки в пределах выполнения справа налево символов, клавиша со стрелкой вправо должна уменьшить смещение вставки, и клавиша со стрелкой влево должна увеличить это.
Перемещение каре через направленную границу еще более усложняется. Следующее число иллюстрирует то, что происходит, когда направленная граница пересекается, когда пользователь перемещается с клавишей со стрелкой. Ступая три позиции направо в выведенный на экран текст соответствует перемещению в смещения символа 7, 19, тогда 18.

У определенных глифов никогда не должно быть каре между ними; вместо этого, каре должно переместиться как если бы глифы, представленные единственный символ. Например, никогда не должно быть каре между o и умляутом, если они представляются двумя отдельными символами.
class обеспечивает методы ( и ) это позволяет Вам легко переместить каре гладко через двунаправленный текст.
Часто, расположение в пространстве устройства должно быть преобразовано в текстовое смещение. Например, когда пользователь щелкает мышью по выбираемому тексту, расположение мыши преобразовывается в текстовое смещение и используется в качестве одного конца диапазона выбора. Логически, это - инверсия расположения каре.
Когда Вы работаете с двунаправленным текстом, единственное визуальное расположение в дисплее может соответствовать двум различным смещениям в исходном тексте, как показано в следующем числе:

Поскольку единственное визуальное расположение может соответствовать двум различным смещениям, совершить нападки, двунаправленный текст тестирования не является только вопросом измеряющихся ширин глифа, пока глиф в корректном расположении не находится и затем отображение что позиция назад к символьному смещению. Обнаружение стороны, что хит шел, помогает различить эти две альтернативы.
Можно выполнить использование тестирования хита . Информация о хите инкапсулируется в a возразите и включает информацию о стороне, что хит шел.
Выбранный диапазон символов представляется графически областью выделения, областью, в которой глифы выводятся на экран с инвертированным видеоизображением или против различного цвета фона.
Выделите области, как каре, более усложняются для двунаправленного текста чем для однонаправленного текста. В двунаправленном тексте у непрерывного диапазона символов не могло бы быть непрерывной области выделения когда выведено на экран. Наоборот, область выделения, показывая визуально непрерывный диапазон глифов не могла бы соответствовать единственному, непрерывному диапазону символов.
Это приводит к двум стратегиям выделения выборов в двунаправленном тексте:
Логическое выделение: С логическим выделением выбранные символы всегда непрерывны в текстовой модели, и области выделения позволяют быть несмежной. Следующее является примером логического выделения:

Визуальное выделение: С визуальным выделением мог бы быть больше чем один диапазон выбранных символов, но область выделения всегда непрерывна. Следующее является примером визуального выделения:

Логическое выделение более просто реализовать, так как выбранные символы всегда непрерывны в тексте.
Выборка

В зависимости от которых API Java Вы используете, у Вас могут быть так немного или такое большое управление текстовым расположением, как Вы нуждаетесь:
Если Вы только хотите вывести на экран блок текста или нуждаться в доступном для редактирования текстовом управлении, можно использовать JTextComponent, который выполнит текстовое расположение для Вас. разрабатывается, чтобы обработать потребности большинства международных приложений и поддерживает двунаправленный текст Для получения дополнительной информации о , см.
Если Вы хотите вывести на экран простую текстовую строку, можно вызвать метод Graphics2D.drawString и позвольте 2-D Java, размечают строку для Вас. Можно также использовать представлять разработанные строки и строки, которые содержат двунаправленный текст. Для получения дополнительной информации о рендеринге текста через , см.
Если Вы хотите реализовать свои собственные подпрограммы редактирования текста, можно использовать TextLayout управлять текстовым расположением, выделением, и поражать обнаружение. Услуги, предоставленные обработайте наиболее распространенные случаи, включая текстовые строки со смешанными шрифтами, смешанными языками, и двунаправленным текстом. Для получения дополнительной информации об использовании TextLayout см. Управляющее текстовое Расположение.
Если Вы хотите полный контроль по тому, как текст формируется и располагается, можно создать свое собственное экземпляры используя class и затем представляет их через class.
Обычно, Вы не должны выполнить текстовые операции расположения самостоятельно. Для большинства приложений, лучшее решение для того, чтобы вывести на экран статический и доступный для редактирования текст. Однако, не поддерживает дисплей двойных каре или несмежных выборов в двунаправленном тексте. Если Ваше приложение требует этих функций, или Вы предпочитаете реализовывать свои собственные подпрограммы редактирования текста, можно использовать Java 2-D текстовые API расположения.
class поддерживает текст, который содержит многократные стили и символы от различных систем письменности, включая арабский и иврит. (Арабский и иврит особенно трудно вывести на экран, потому что следует изменить и переупорядочить текст, чтобы достигнуть приемлемого представления.)
упрощает процесс отображения и измерения текста, даже если Вы работаете с текстом только для английского языка. При использовании , можно достигнуть высококачественного книгопечатания без дополнительного усилия.
разрабатывается так, чтобы не было никакого существенного воздействия производительности, когда это используется, чтобы вывести на экран простой, однонаправленный текст. Есть некоторые дополнительные издержки обработки когда используется, чтобы вывести на экран арабский или еврейский текст. Однако, это обычно находится на порядке микросекунд на символ и во власти выполнения нормального кода для прорисовки.
class управляет расположением и упорядочиванием глифов для Вас. Можно использовать сделать следующее:
автоматически размечает текст, включая двунаправленный текст, с корректным формированием и упорядочиванием. Правильно сформировать и упорядочить глифов, представляющих строку текста, должен знать полный контекст текста:
Основное направление текста обычно устанавливается атрибутом (стиль) на тексте. Если тот атрибут отсутствует, TextLayout следует за Unicode двунаправленный алгоритм и получает основное направление из начальных символов в абзаце.
поддерживает информацию о каре, такую как каре , позиция, и угол. Можно использовать эту информацию, чтобы легко вывести на экран каре и в однонаправленном и в двунаправленном тексте. Когда Вы тянете каре для двунаправленного текста, используя гарантирует, что каре будут расположены правильно.
обеспечивает каре значения по умолчанию Shapes и автоматически поддерживает двойные каре. Для курсива и наклонных глифов, производит повернутые каре, как показано в следующем числе. Эти позиции каре также используются в качестве границ между глифами для выделения и поражают тестирование, которое помогает произвести непротиворечивый пользовательский опыт.

Учитывая смещение вставки, метод возвращает массив с двумя элементами объекты: элемент 0 содержит каре strong, и элемент 1 содержит слабое каре, если Вы существуете. Чтобы вывести на экран двойные каре, Вы просто тянете оба каре объекты; каре будут автоматически быть представленными в корректных позициях.
Если Вы хотите использовать пользовательские каре, можно получить позицию и угол каре от и привлеките их непосредственно.
Выборка
Щелчок по o на стороне o к еврейским текстовым записям, что конечный пользователь, по которому щелкают после o, который является частью английского текста. Это располагает слабое (черное) каре рядом с o и каре strong (красное) перед H:

Щелчок по пространству направо от записей o, что конечный пользователь, по которому щелкают пространство, которое является частью еврейского текста. Это располагает strong (красное) каре рядом с o и слабое каре (черное) перед H:

Можно также использовать TextLayout class, чтобы определить получающееся смещение вставки, когда пользователь нажимает левую или правую клавишу со стрелкой. Данный a TextHitInfo объект, который представляет текущее смещение вставки, метод возвращает a объект, который представляет корректное смещение вставки, если клавиша со стрелкой вправо нажимается. метод предоставляет ту же самую информацию для клавиши со стрелкой влево.
Следующая выборка от выборки
public class ArrowKeySample extends JPanel implements KeyListener {
// ...
private static void createAndShowGUI() {
// Create and set up the window.
ArrowKey demo = new ArrowKey();
frame = new JFrame("Arrow Key Sample");
frame.addKeyListener(demo);
// ...
}
private void handleArrowKey(boolean rightArrow) {
TextHitInfo newPosition;
if (rightArrow) {
newPosition = textLayout.getNextRightHit(insertionIndex);
} else {
newPosition = textLayout.getNextLeftHit(insertionIndex);
}
// getNextRightHit() / getNextLeftHit() will return null if
// there is not a caret position to the right (left) of the
// current position.
if (newPosition != null) {
// Update insertionIndex.
insertionIndex = newPosition.getInsertionIndex();
// Repaint the Component so the new caret(s) will be displayed.
frame.repaint();
}
}
// ...
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_RIGHT) {
handleArrowKey(keyCode == KeyEvent.VK_RIGHT);
}
}
}
TextLayout class обеспечивает простой механизм для текста тестирования хита. метод берет x и координаты y от мыши как параметры и возвращает a объект. содержит смещение вставки для указанной позиции и стороны, что хит шел. Смещение вставки является смещением, самым близким к хиту: если хит проходит конец строки, смещение в конце строки возвращается.
Следующая выборка от
private class HitTestMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
Point2D origin = computeLayoutOrigin();
// Compute the mouse click location relative to
// textLayout's origin.
float clickX = (float) (e.getX() - origin.getX());
float clickY = (float) (e.getY() - origin.getY());
// Get the character position of the mouse click.
TextHitInfo currentHit = textLayout.hitTestChar(clickX, clickY);
insertionIndex = currentHit.getInsertionIndex();
// Repaint the Component so the new caret(s) will be displayed.
repaint();
}
}
Можно получить a Shape это представляет область выделения от . автоматически принимает контекст во внимание, вычисляя размерности области выделения. поддерживает и логическое и визуальное выделение.
Следующая выборка от
public void paint(Graphics g) {
// ...
boolean haveCaret = anchorEnd == activeEnd;
if (!haveCaret) {
// Retrieve highlight region for selection range.
Shape highlight =
textLayout.getLogicalHighlightShape(anchorEnd, activeEnd);
// Fill the highlight region with the highlight color.
graphics2D.setColor(HIGHLIGHT_COLOR);
graphics2D.fill(highlight);
}
// ...
}
// ...
private class SelectionMouseMotionListener extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
Point2D origin = computeLayoutOrigin();
// Compute the mouse location relative to
// textLayout's origin.
float clickX = (float) (e.getX() - origin.getX());
float clickY = (float) (e.getY() - origin.getY());
// Get the character position of the mouse location.
TextHitInfo position = textLayout.hitTestChar(clickX, clickY);
int newActiveEnd = position.getInsertionIndex();
// If newActiveEnd is different from activeEnd, update activeEnd
// and repaint the Panel so the new selection will be displayed.
if (activeEnd != newActiveEnd) {
activeEnd = newActiveEnd;
frame.repaint();
}
}
}
private class SelectionMouseListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
Point2D origin = computeLayoutOrigin();
// Compute the mouse location relative to
// TextLayout's origin.
float clickX = (float) (e.getX() - origin.getX());
float clickY = (float) (e.getY() - origin.getY());
// Set the anchor and active ends of the selection
// to the character position of the mouse location.
TextHitInfo position = textLayout.hitTestChar(clickX, clickY);
anchorEnd = position.getInsertionIndex();
activeEnd = anchorEnd;
// Repaint the Panel so the new selection will be displayed.
frame.repaint();
}
}
Метод SelectionMouseListener.mousePressed определяет переменную anchorEnd, который является позицией в тексте, где мышью щелкнули. Метод SelectionMouseMotionListener.mouseDragged определяет переменную activeEnd, который является позицией в тексте туда, где мышь была перетащена. paint метод получает a Shape объект, который представляет выбранный текст (текст между позициями anchorEnd и activeEnd). paint метод тогда заполняется объект с цветом выделения.