Материал: Портянкин И. Swing

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

220

ГЛАВА 8

Поддержка надписями JLabel языка HTML возводит их в ранг универсального информационного элемента, позволяющего вывести любой тип информации. Многострочные надписи, различные шрифты и выравнивания, любые цвета, нумерованные и маркированные списки, изображения — все у вас в руках. Однако чересчур увлекаться возможностями HTML не стоит, потому что надписи должны сообщать пользователю полезную информацию, а не отвлекать его внимание буйством красок. К тому же HTML-текст выводится на надписи в своеобразной форме, несколько отличающейся от того, что показало бы большинство браузеров, и все это может привести к визуальному конфликту между стилем используемого внешнего вида и некоторыми компонентами, поэтому необходимо точно знать, что вы хотите получить.

Надписи и события

Надпись JLabel — такой же компонент, как и остальные, унаследованный от базового класса JComponent, поэтому она может обрабатывать любые виды общих для всех компонентов событий: надо лишь добавить к ней соответствующих слушателей. Но чаще всего надпись просто сообщает что-то пользователю, а не обрабатывает событий, чтобы не вводить его в заблуждение (помните принцип простого интерфейса с очевидным предназначением). Пользователь привык, что надписи выводят информацию, и не отвечают за что-то большее. Если вам нужно выполнять в приложении какую-то функцию, инициируйте ее выполнение с помощью кнопки или клавиатурного сокращения, в качестве альтернативы можно предложить компонент-гиперссылку JXHyperlink из пакета дополнений SwingX.

Надписи также не принимают фокус ввода, их свойство focusable по умолчанию установлено в false. Если только вы не хотите огорошить пользователей новаторским интерфейсом, в котором надписи живут своей жизнью, стандартное поведение вряд ли стоит менять.

Надписи и мнемоники

Создатели Swing добавили в надписи JLabel еще одну возможность, позволяющую отточить функциональность вашего пользовательского интерфейса. Надписи могут поддерживать мнемоники (mnemonics) для других компонентов, неспособных поддерживать их самостоятельно. Мнемоника — это специальное клавиатурное сокращение (на большинстве платформ сочетание клавиши Alt или Ctrl с кодом клавиши), позволяющая быстро активировать некоторый компонент интерфейса, например, кнопку или текстовое поле. В сложных интерфейсах, состоящих из множества компонентов, находить нужный компонент (который, возможно, является самым важным) может быть утомительно, и в таких ситуациях мнемоники очень полезны. Более того, они незаменимы для пользователей с ограниченными возможностями, которые не могут пользоваться мышью. Приложение высокого класса обязано предоставлять доступ с клавиатуры ко всем своим компонентам.

Некоторые компоненты, например кнопки, сами поддерживают мнемоники, другие, такие как текстовые поля или раскрывающиеся списки, могут поддерживать клавиатурные сокращения, но удобно информировать о них пользователя не в состоянии. Здесь пригодится надпись с мнемоникой около компонента: пользователь быстро увидит, как активируется данный компонент, потому что символ мнемоники в тексте надписи подчеркивается.

Поддержка мнемоник реализована в UI-представителе надписи JLabel, причем сделано все довольно интересно: когда вы сообщаете надписи, что хотели бы использовать ее для вывода мнемоники некоторого компонента, UI-представитель, во-первых, подчеркивает символ мнемоники при прорисовке надписи, во-вторых, регистрирует в кар-

Вывод вспомогательной информации

221

те входных событий нужное клавиатурное сокращение. При срабатывании сокращения надпись на мгновение получает фокус ввода (фокус сохраняется на надписи, пока вы удерживаете клавиши), при отпускании клавиш фокус переходит к компоненту, для которого была задана мнемоника, а затем надпись снова возвращается в обычное состояние (без фокуса ввода). Давайте увидим все в действии:

//LabelMnemonic.java

//Использование надписей для вывода мнемоник import javax.swing.*;

import java.awt.*;

public class LabelMnemonic extends JFrame { public LabelMnemonic() {

super("LabelMnemonic"); setDefaultCloseOperation(EXIT_ON_CLOSE); // добавим пару текстовых полей

JPanel contents = new JPanel(new GridLayout(2,2)); JTextField tf = new JTextField(10);

JLabel label = new JLabel("Ваше имя:");

//настройка мнемоники label.setLabelFor(tf); label.setDisplayedMnemonic('И');

//добавляем компоненты в таблицу contents.add(new JLabel("Ваша фамилия:")); contents.add(new JTextField(10)); contents.add(label);

contents.add(tf);

//выведем окно на экран setContentPane(contents); pack(); setVisible(true);

}

public static void main(String args[]) { SwingUtilities.invokeLater(

new Runnable() {

public void run() { new LabelMnemonic(); } });

}

}

В примере мы создаем небольшое окно, в качестве панели содержимого которого используется панель с табличным расположением (2 строки и 2 столбца). В панель мы добавляем два текстовых поля и надписи к ним (весьма часто встречающаяся в пользовательском интерфейсе комбинация). Текстовое поле не может отобразить мнемонику, и здесь нам пригодится надпись. Мы настраиваем мнемонику для одной из созданных нами надписей: указываем компонент, активизируемый при срабатывании мнемоники

222

ГЛАВА 8

(setLabelFor()), а также символ мнемоники, клавишу которого вместе с управляющей клавишей и нужно будет нажать (setDisplayedMnemonic()). Запустив пример, вы увидите, что надпись подсказывает пользователю, каким символом можно активизировать текстовое поле при нажатии нужного сочетания (чаще всего Alt+символ, в нашем случае Alt+И). В текущих выпусках JDK 1.6 -- 1.7 кириллические символы поддерживаются4, что замечательно, так как в первом издании книги мы сломали немало копий по этому поводу.

Общая рекомендация для интерфейса говорит, что все компоненты должны быть снабжены мнемониками, поэтому рассмотренная нами возможность несомненно полезна.

Всплывающие подсказки

Всплывающие подсказки (tool tips) — неизменный атрибут современного пользовательского интерфейса, и не зря: они намного упрощают ознакомление и последующую работу с вашим приложением. Это небольшие (чаще всего, хотя и не обязательно) текстовые описания компонентов вашего интерфейса, появляющиеся рядом с компонентом в том случае, если пользователь ненадолго задерживает на нем указатель мыши. Ценность всплывающих подсказок трудно переоценить — они намного ускоряют работу с любым, особенно сложным приложением. Вместо знакомства с документацией пользователь может прямо «на лету» узнать, для чего предназначен тот или иной элемент интерфейса, и быстро начать работу. Работу кнопками, на которых есть только значки, вообще невозможно представить без подсказок5. В Swing это особенно верно, потому что подсказки здесь обладают весьма широкими возможностями.

Любой компонент Swing может обладать всплывающей подсказкой, потому что поддержка их встроена в базовый класс библиотеки JComponent. Когда вы вызываете метод setToolTipText(), компонент регистрирует себя в классе ToolTipManager, который отвечает за правильный вывод подсказок. Класс ToolTipManager следит за перемещениями мыши на всех зарегистрированных в нем компонентах и при наступлении нужного момента (наведении указателя мыши) выводит подсказку на экран. Рассмотрим пример с подсказками:

//ToolTips.java

//Подсказки в Swing import javax.swing.*; import java.awt.*; import java.awt.event.*;

public class ToolTips extends JFrame {

4 К сожалению, только для надписей, но не для кнопок и меню.

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

Вывод вспомогательной информации

223

public ToolTips() { super("ToolTips");

setDefaultCloseOperation(EXIT_ON_CLOSE);

//добавим несколько кнопок с подсказками

JButton b1 = new JButton("Один"); b1.setToolTipText("Это первая кнопка"); JButton b2 = new JButton() {

public Point getToolTipLocation(MouseEvent e) { return new Point(10, 10);

}

public String getToolTipText(MouseEvent e) { if ( e.getY() > 10 ) {

return "Нижняя часть кнопки!";

}

return super.getToolTipText(e);

}

}; b2.setText("Два");

b2.setToolTipText("<html><h3>Это вторая кнопка.<ul>" + "Она:<li>Ничего не делает<li>Но ее можно нажать!");

JPanel contents = new JPanel(); contents.add(b1); contents.add(b2);

//выводим окно на экран

add(contents); setSize(400, 150); setVisible(true);

}

public static void main(String[] args) { SwingUtilities.invokeLater(

new Runnable() {

public void run() { new ToolTips(); } });

}

}

Мы добавляем в окно две кнопки JButton, и задаем для каждой из них текст подсказки, что автоматически приводит к регистрации кнопок в классе ToolTipManager. Для первой кнопки мы используем простой текст, который появится в виде однострочной подсказки, шрифт и цвет которой зависят от текущих внешнего вида и расположения. Но вот для второй кнопки мы используем уже знакомый нам HTML-текст (помните, что начинать HTML-строку следует с символов <html>), и здесь у вас, так же как и в случае с надписями, просто безграничные возможности. Вы можете задействовать любые возможности HTML версии 3.2 для создания краткой, но мощной системы помощи, действующей прямо «на лету». В примере мы применили стиль заголовка и маркированный список — эти

224

ГЛАВА 8

элементы могут использоваться для перечисления возможностей компонента. С другой стороны, стоит помнить о том, что большие и красочные подсказки, неожиданно загораживающие экран при остановке указателя мыши на любом компоненте, могут раздражать пользователя — подробные описания функций приложения стоит оставлять для общей системы помощи.

Помимо метода setToolTipText(), позволяющего задать для вашего компонента подсказку, увасестьещепараметодов,способныхповлиятьнаеевывод,—этометодыgetToolTipLocation() и getToolTipText(MouseEvent), определенные в базовом классе JComponent. Правда, пользоваться ими довольно неудобно, потому что соответствующего метода set нет, и для получения нужного эффекта их приходиться переопределять, что мы и сделали в нашем примере, создав анонимный подкласс кнопки JButton. Метод getToolTipLocation() позволяет указать классу ToolTipManager, в каком месте экрана следует выводить подсказку относительно компонента, для которого подсказка выводится. Можно указывать различные места для подсказки в зависимости от события MouseEvent, по которому подсказка выводится. В примере мы указали, что подсказка должна выводиться на расстоянии 10 пикселов по осям X и Y от верхнего левого угла нашей кнопки (можно указывать и отрицательные расстояния, это будет означать, что вы хотите вывести подсказку не ниже компонента, как обычно, а выше). Правда, действует описанный механизм, только если подсказка выводится как легковесный компонент, то есть когда ей хватает места в пределах окна нашего приложения. В противном случае класс ToolTipManager сам решает, где удобнее ее разместить. Полученный эффект вы сможете наблюдать, запустив программу с примером: подсказка первой кнопки будет выводиться в разных местах, в зависимости от положения указателя мыши, а для второй кнопки она всегда будет появляться на указанном нами расстоянии (если ей хватит места). Метод getToolTipText() позволяет выводить для одного и того же компонента различные подсказки в зависимости от того, где пользователь задержал указатель мыши (координаты этого места позволяет узнать объект MouseEvent). Данный метод часто задействуется сложными компонентами Swing, такими как списки или таблицы, состоящими из многих элементов. С его помощью они обеспечивают вывод собственных подсказок для каждого элемента. По умолчанию он возвращает для любой точки текст, заданный методом setToolTipText(), но переопределив этот метод, вы сможете изменить подобное поведение. В примере мы используем подсказку по умолчанию только для верхней части кнопки (высотой в 10 пикселов), а для нижней части возвращаем собственный текст.

Механизм работы всплывающих подсказок в Swing довольно прост. Как мы уже отмечали, при вызове метода setToolTipText() компонент регистрирует себя в классе ToolTipManager. Последний начинает следить за перемещениями мыши в компоненте (причем для всех компонентов используется один и тот же слушатель событий от мыши, поскольку для каждого события можно узнать его источник — компонент, к которому оно относится). Когда указатель мыши входит в область компонента (вызывается метод

Источник: https://studfile.net/preview/15935977/