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

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

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

225

слушателя mouseEntered()), класс ToolTipManager запускает таймер, при срабатывании которого (если при этом не происходит движение мыши, иначе таймер запускается заново) на экран выводится подсказка. Подсказка создается в два этапа. Собственно компонентподсказка JToolTip создается методом createToolTip(), имеющимся в любом компоненте Swing. Другой компонент (тот, что будет «всплывать» над остальными компонентами, в нем размещается подсказка JToolTip) создается с помощью вспомогательного класса PopupFactory. Этот класс определяет тип компонента (легковесный или тяжеловесный) и размещает его в нужном месте экрана (в слое POPUP_LAYER многослойной панели или в новом окне без рамки JWindow). Общую картину иллюстрирует рис. 8.1.

Компонент

 

ToolTipManager

 

PopupFactory

 

 

 

 

 

 

 

 

 

 

 

 

setToolTipText()

registerComponent()

mouseEntered()

enterTimer.start()

showTipWindow()

createToolTip()

getPopup()

Подсказка на экране

Рис. 8.1. Схема вывода всплывающей подсказки

Когда подсказка уже находится на экране, класс ToolTipManager запускает таймер exitTimer, при срабатывании которого она скрывается. Также во время нахождения подсказки на экране ToolTipManager следит за фокусом компонента (с помощью слушателя FocusListener) и щелчками мыши. В случае если пользователь щелкает мышью, когда ее указатель находится на компоненте или подсказке, или компонент теряет фокус ввода, подсказка скрывается.

УвасестьвозможностьуправлятьнекоторымиаспектамиработыклассаToolTipManager. Прежде всего, вы можете переопределить метод createToolTip() в вашем компоненте, если вам понадобится предоставить для него какую-то особенную подсказку, но делать это слишком часто не рекомендуется. Лучше, если у приложения имеется единый продуманный облик, и подсказки в него органично вписываются. Если вас не устраивают подсказки, предоставляемые используемым вашим приложением внешним видом, лучше всего написать для них новый UI-представитель. С другой стороны, имеются стандартные варианты настройки подсказок, и мы их сейчас рассмотрим.

Настройка подсказок

Класс ToolTipManager позволяет настраивать параметры вывода подсказок на экран. В первую очередь это относится ко времени, которое проходит перед появлением подсказки, времени ее нахождения на экране и еще к некоторым параметрам, позволяющим тонко управлять всплывающими подсказками в вашем приложении. Параметры,

226

ГЛАВА 8

заданные по умолчанию, удачно выбраны, и менять их придется редко, но знать их все же полезно. Кроме того, вы можете «намекнуть» о том, какой элемент вы бы хотели видеть в качестве «хозяина» подсказки, легковесный или тяжеловесный. Рассмотрим теперь пример настройки подсказок, а затем обсудим их параметры в деталях:

//ToolTipsTuning.java

//Настройка подсказок import javax.swing.*;

public class ToolTipsTuning extends JFrame { public ToolTipsTuning() {

super("ToolTipsTuning"); setDefaultCloseOperation(EXIT_ON_CLOSE);

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

JPanel contents = new JPanel(); JButton b1 = new JButton("Первая");

b1.setToolTipText("Подсказка для первой"); JButton b2 = new JButton("Вторая"); b2.setToolTipText("Подсказка для второй"); contents.add(b1);

contents.add(b2);

//настройка подсказок

ToolTipManager ttm = ToolTipManager.sharedInstance();

ttm.setLightWeightPopupEnabled(false);

ttm.setInitialDelay(1000);

ttm.setDismissDelay(500);

ttm.setReshowDelay(1000); // выводим окно на экран add(contents); setSize(200, 100); setVisible(true);

}

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

new Runnable() {

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

}

}

Как и в предыдущем примере, мы добавляем в окно две кнопки, для которых включаем вывод подсказок. Далее с помощью экземпляра класса ToolTipManager (нетрудно видеть, что он представляет собой классического одиночку, экземпляр которого возвращает метод sharedInstance()) мы производим настройку подсказок нашего приложения. Доступные свойства перечислены в табл. 8.2.

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

227

Таблица 8.2. Свойства класса ToolTipManager

Свойство

Описание

lightWeightPopupEnabled

Рекомендует классу ToolTipManager использовать для подсказок

 

легковесные компоненты, которые затем появятся в слое POPUP_

 

LAYER многослойной панели. Если значение равно false, подсказ-

 

ки размещаются либо в тяжеловесных компонентах (если места

 

в окне достаточно), либо в собственных окнах без рамки (когда

 

места не хватает). Следит за этим фабрика классов PopupFactory,

 

предназначенная для всплывающих окон. Это свойство может

 

быть полезно, если вы совмещаете в одном окне тяжеловесные

 

и легковесные компоненты, и велика вероятность того, что легко-

 

весные подсказки могут быть скрыты тяжеловесными компонен-

 

тами

initialDelay

Задержка (в миллисекундах) между остановкой указателя мыши

 

на компоненте и появлением подсказки

dismissDelay

Время, в течение которого подсказка остается на экране (если

 

только не происходит каких-то других событий, например, потери

 

окном фокуса)

reshowDelay

Время, в течение которого действует «режим подсказок». Если

 

пользователь, прочитав подсказку для одного компонента, тут же

 

переводит указатель мыши на другой компонент, подсказка для

 

второго компонента выводится незамедлительно

Впримере мы использовали довольно необычные значения описанных свойств,

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

Рамки

Рамки (borders) библиотеки Swing позволяют визуально упорядочить пользовательский интерфейс, разделяя компоненты по их функциям и назначению. Также довольно часто они используются в качестве «украшения» для того или иного компонента библиотеки, и нередко именно рамка определяет особый колорит компонента. Если вы вспомните внешний вид кнопок JButton, специальные границы текстовых полей или панелей прокрутки, то убедитесь, что основу внешнего вида таких компонентов иногда составляет необычная рамка.

В качестве визуально организующего элемента рамки чаще всего используются для панелей JPanel, основных строительных кирпичиков, в которых вы размещаете свои компоненты с помощью того или иного менеджера расположения. В конечном итоге интерфейс складывается из множества определенным образом расположенных панелей JPanel, и панели, содержащие часть элементов интерфейса, отвечающих за определенные функции, удобно «помещать в рамку». Благодаря таким рамкам пользователю проще освоиться с приложением, потому что он быстро определяет, какая часть интерфейса за что отвечает, и без дополнительных усилий находит то, что ему нужно.

228

ГЛАВА 8

Поддержка рамок обеспечивается рисующими механизмами базового класса JComponent (детали мы исследовали в главе 4), так что для любого компонента Swing вы можете использовать нужную вам рамку. Рамка хранится в качестве свойства border, сменить или получить ее позволяют методы get/set. Обязанности рамок в Swing описаны в интерфейсе Border из пакета javax.swing.border, в этом же пакете находится впечатляющее количество стандартных рамок. Давайте рассмотрим пример и ознакомимся

сними:

//Borders.java

//Рамки Swing import javax.swing.*;

import javax.swing.border.*; import java.awt.*;

public class Borders extends JFrame { public Borders() {

super("Borders"); setDefaultCloseOperation(EXIT_ON_CLOSE);

//создаем панели с всевозможными рамками

JPanel contents = new JPanel( new GridLayout(3, 2, 5, 5));

contents.add(createPanel(new TitledBorder( "Рамка с заголовком"), "TitledBorder"));

contents.add(createPanel(new EtchedBorder(), "EtchedBorder"));

contents.add(createPanel(new BevelBorder( BevelBorder.LOWERED), "BevelBorder"));

contents.add(createPanel(new SoftBevelBorder( BevelBorder.RAISED), "SoftBevelBorder"));

contents.add(createPanel(new LineBorder( Color.BLACK, 5), "LineBorder")); contents.add(createPanel(new MatteBorder(

new ImageIcon("matte.gif")), "MatteBorder"));

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

add(contents);

pack();

setVisible(true);

}

// метод создает панель с рамкой и надписью private JPanel createPanel(Border b, String text) {

JPanel panel = new JPanel(new BorderLayout()); panel.add(new JLabel(text)); panel.setBorder(new CompoundBorder(

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

229

b, new EmptyBorder(30, 30, 30, 30))); return panel;

}

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

new Runnable() {

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

}

}

В примере мы создаем окно с панелью в центре, для которой выбираем табличное расположение с шестью ячейками; именно шесть наиболее употребительных рамок содержит пакет javax.swing.border. В ячейки табличного расположения мы добавляем панели с установленными рамками и надписью JLabel, которая помогает разобраться, какой класс позволяет создать ту или иную рамку. При этом используется вспомогательный метод createPanel(), который создает новую панель с полярным расположением, в центр ее добавляет надпись и устанавливает нужную рамку Border. Заметьте, что метод createPanel() «украшает» панели с помощью сразу трех рамок: собственно панель получает в качестве рамки объект CompoundBorder, позволяющий совместить две рамки в одну. Внешней рамкой является та, которая передается в метод в качестве параметра, а внутренняя рамка для всех панелей одна — это рамка EmptyBorder, оставляющая между границей панели и ее содержимым пустое пространство, чтобы надпись с названием рамки было проще читать. Запустив программу с примером, вы сможете насладиться разнообразием рамок Swing, и это только начало: каждая из рассмотренных нами шести рамок имеет дополнительные варианты оформления.

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