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

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

Меню и панели инструментов

265

}

public void actionPerformed(ActionEvent e) { System.exit(0);

}

}

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

new Runnable() {

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

}

}

Итак, в этом примере создается относительно простая система меню. Как мы уже отмечали, элементы меню — это фактически кнопки, собранные в список. Списки элементов меню, или правильнее выпадающие меню (drop-down menus), реализованы в Swing классом JMenu. Именно они создаются методами createFileMenu() и createWhoMenu(), внутри которых в выпадающие меню методом add() добавляются разнообразные элементы меню, в том числе элементы-флажки и элементыпереключатели. После этого остается вывести созданные выпадающие меню на экран, для чего служит так называемая строка меню (menu bar), создать которую позволяет класс JMenuBar. В нем также есть метод add(), только не для элементов меню, а для выпадающих меню JMenu. Разместив все выпадающие меню своего приложения в строке меню, вы можете поместить ее в окно, вызвав предназначенный для этого метод setJMenuBar().

Что касается элементов меню, то это те же кнопки, флажки и переключатели. Вы можете указывать для них названия, значки и мнемоники, создавать их на основе интерфейса Action, и все это проиллюстрирует наш пример. Единственное новшество в примере — это разделитель (separator), который позволяет организовать смысловые группы в выпадающих меню. В примере показано, как его создать, а подробнее мы поговорим о нем чуть позже.

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

266

ГЛАВА 10

Строка меню JMenuBar

Главное, что нужно помнить при создании строки меню JMenuBar в своей программе, — это самый обыкновенный контейнер, ничем не отличающийся от панели JPanel и обладающий теми же самыми свойствами. Не нужно думать, что строка меню рождена только для работы с выпадающими меню. Вы можете смело добавлять в нее всевозможные компоненты, например надписи со значками или раскрывающиеся списки. Беззастенчиво заглянув внутрь класса JMenuBar, можно увидеть, что даже менеджер расположения у строки меню не какой-то экзотический, а прекрасно знакомый нам менеджер BoxLayout с расположением компонентов по горизонтали. Так что создание с виду совершенно новаторского меню оказывается весьма простым делом. Например, можно сделать со строкой меню следующее:

//TrickyMenuBar.java

//Полоска меню JMenuBar может многое import javax.swing.*;

import java.awt.*;

public class TrickyMenuBar extends JFrame { public TrickyMenuBar() {

super("TrickyMenuBar"); setDefaultCloseOperation( EXIT_ON_CLOSE );

//создаем главную полоску меню

JMenuBar menuBar = new JMenuBar();

//добавляем в нее выпадающие меню menuBar.add(new JMenu("Файл")); menuBar.add(new JMenu("Правка"));

//мы знаем, что используется блочное

//расположение, так что заполнитель

//вполне уместен menuBar.add(Box.createHorizontalGlue());

//теперь поместим в полоску меню

//не выпадающее меню, а надпись со значком

JLabel icon = new JLabel(

new ImageIcon("images/download.gif")); icon.setBorder(

BorderFactory.createLoweredBevelBorder());

menuBar.add(icon);

//помещаем меню в наше окно setJMenuBar(menuBar);

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

setSize(300, 200); setVisible(true);

}

public static void main(String[] args) {

Меню и панели инструментов

267

SwingUtilities.invokeLater( new Runnable() {

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

}

}

В примере мы сначала добавили в строку меню традиционные выпадающие меню (они, правда, для экономии места были оставлены пустыми), а затем, предварительно использовав заполнитель, поместили в строку меню самую обычную надпись со значком, установив для нее тисненую рамку. Мы специально использовали анимированный GIF-файл, чтобы пример произвел еще более сильный эффект. Не правда ли, напоминает современные браузеры? И все, что мы сделали для этого, — это добавили два компонента.

Отметьте также, что размещение строки меню в окне осуществляется не с помощью обычного метода add() и менеджера расположения, а с помощью специального метода setJMenuBar(). Этот метод на самом деле принадлежит не классу окна JFrame, а корневой панели JRootPane, которая и заботится о том, чтобы строка меню занимала подобающее ей положение на вершине окна, оставляя вам все пространство в панели содержимого.

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

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

Выпадающие меню JMenu и разделители JSeparator

Как мы уже отмечали, для упорядочения элементов меню служат выпадающие меню JMenu. Интересно, что класс JMenu унаследован от обычного элемента меню JMenuItem, и его функция заключается только в том, чтобы при щелчке мышью показать в нужном месте экрана всплывающее меню, в котором и содержатся все добавленные элементы меню. Ничего хитрого в этом классе нет, и сказать о нем можно только то, что он позволяет организовывать вложение меню любой сложности. Для этого вы просто вкладываете выпадающие меню друг в друга, и получаете перечни элементов меню произвольной длины (каскадные меню).

Для того чтобы организовать в меню несколько групп элементов, используются разделители JSeparator. Мы можете добавлять их в выпадающие меню, создавая напрямую, или же использовать для этого специальный метод addSeparator(). Кроме того разделите-

268

ГЛАВА 10

ли можно применять и вне меню в качестве разделительных линий, в том числе вертикальных. Рассмотрим пример:

//CascadedMenus.java

//Создание вложенных меню любой сложности import javax.swing.*;

import java.awt.*;

public class CascadedMenus extends JFrame { public CascadedMenus() {

super("CascadedMenus"); setDefaultCloseOperation( EXIT_ON_CLOSE );

//создаем строку главного меню

JMenuBar menuBar = new JMenuBar();

//создаем выпадающее меню

JMenu text = new JMenu("Текст");

//и несколько вложенных меню

JMenu style = new JMenu("Стиль"); JMenuItem bold = new JMenuItem("Жирный");

JMenuItem italic = new JMenuItem("Курсив"); JMenu font = new JMenu("Шрифт");

JMenuItem arial = new JMenuItem("Arial"); JMenuItem times = new JMenuItem("Times"); font.add(arial);

font.add(times);

//размещаем все в нужном порядке style.add(bold); style.add(italic); style.addSeparator(); style.add(font);

text.add(style);

menuBar.add(text);

//помещаем меню в окно setJMenuBar(menuBar);

//разделитель может быть полезен не только в меню

((JComponent)getContentPane()).setBorder( BorderFactory.createEmptyBorder(0, 5, 0, 0));

add(new JSeparator(SwingConstants.VERTICAL), "West");

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

setSize(300, 200); setVisible(true);

}

Меню и панели инструментов

269

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

new Runnable() {

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

}

}

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

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

В примере была создана очень простая система меню, обычно она в несколько раз больше и сложнее. Но даже для такой простой системы код получился немного неряшливым (чего стоят одни только добавления одного в другого, а другого в третье). Действительно, инструкции создания меню в коде сильно «загрязняют» последний, это хорошо известный факт, что «декларативный» стиль описания объекта не слишком элегантно выглядит через призму вызовов объектно-ориентированных методов. Мы ведь просто хотим указать структуру меню, а не вызываем никаких действий. Чуть позже мы попытаемся решить эту проблему.

Клавиатурные сокращения и мнемоники

Если часто работаешь с одним и тем же приложением, и раз за разом выполняешь одни и те же операции, поневоле хочется повысить свою производительность и не тратить время на то, что делалось уже много раз. Именно для этого в графических приложениях и появились клавиатурные сокращения, или клавиши быстрого доступа (accelerators) и мнемоники (mnemonics). Опытные пользователи высоко ценят возможность выполнить операцию, требующую в обычных условиях долгих «блуж-

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