Верхушка 13
Детище меню

В сосуд сорта Frame заложена реальность директивы стандартной строчки меню (menu bar), располагаемой ниже строчки заголовка, как показано на рис. 13.1. Эта строчка — предмет сорта MenuBar.

Целое, что нужно совершить для директивы строчки меню в сосуде Frame — настоящее создать предмет сорта MenuBar и повернуться к способу setMenuBar ():

Frame f = new Frame("Прототип меню"); 

MenuBar mb = new MenuBar(); 

f.setMenuBar(mb);

Если имя mb не потребуюсь, можно соединить два итоговых воззвания к приемам:

f.setMenuBar(new MenuBar());

Разумеется, строчка меню снова свободна и этапы меню не созданы.

Каждый ингредиент строчки меню — выпадающее меню (drop-down menu ) — настоящее предмет сорта Menu. Создать данные предметы и занести их в строчку меню совсем не сложнее, чем создать строчку меню:

Menu mFile = new Menu("Файл");

mb.add(mFile);

Menu mEdit = new Menu("Правка");

mb.add(mEdit);

Menu mView = new Menu("Тип");

mb.add(mView);

Menu mHelp = new Menu("Сноска");

mb.setHelpMenu(mHelp);

и т. д. Ингредиенты располагаются налево вправо в регламенте воззваний к способам add(), как показано на рис. 13.1. В многих графических строить принято меню Информация (Help) прижимать к справедливому краю строчки меню. Сие доносится воззванием к приему setHelpMenu (), но фактическое расположение меню Ссылка определяется графической оберткой.

  Рис. 13.1. Организация меню

Далее определяем каждое выпадающее меню, создавая его этапы. Каждый этап меню — сие предмет сорта Menuitem. Модель его произведения и добавления к меню точно такая же, как и подлинного меню:

Menuitem create = new Menuitem("Создать"); 

mFile.add(create);

Menuitem open = new Menuitem("Раскрыть..."); 

mFile.add(open);

и т. д. Этапы меню духи склонны сверху долу в распорядке воззвания к приемам add().

Зачастую этапы меню объединяются в организации. Одна команда от прочий отделяется горизонтальной нечистью. На рис. 13.1 нечисть проведена меж группами Раскрыть и Послать. Эта нечисть образовывает способом addseparator () сорта Menu или определяется как этап меню со надписью специфического образа — дефисом:

mFile.addfnew Menuitem("-"));

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

Menu send = new Menu("Послать"); 

mFile.add(send);

Тут меню send добавляется в меню mFile как один из его этапов. Подменю send заполняется этапами меню как простое меню.

Нередкий группы меню формируют для отбора из них каких-то допустимостей, будто деталям checkbox. Таковые этапы можно выделить щелчком кнопки мышки или отменить выделение повторным щелчком. Данные группы — предметы сорта CheckboxMenuItem:

CheckboxMenuItem disk = new CheckboxMenuItem("Винчестер A:", true);

send.add(disk);

send.add(new CheckboxMenuItem("Архив")) ;

И Т.Д.

Целое, что получилось в счете перечисленных воздействий, показано на рис. 13.1.

Многие графические скорлупы, но не MS Windows, разрешают учреждать отсоединяемые (tear-off) меню, которые можно перемещать по дисплею. Настоящее показывает в конструкторе

Menu(String label, boolean tearOff)

Если tearoff == true и графическая скорлупа может учреждать отсоединяемое меню, то оно будет создано. В неприятном курьезе настоящий резон свободно игнорируется.

Наконец, надо предназначить деяния группам меню. Группы меню сорта Menuitem порождают происшествия сорта ActionEvent, оттого нужно присоединить к ним предмет класса-слушателя как к ординарным деталям, записав что-то вроде

create.addActionListener(new SomeActionEventHandler())

 open.addActionListener(new AnotherActionEventHandler())

Этапы сорта CheckboxMenuItem порождают явления сорта ItemEvent, оттого надо обращаться к объекту-слушателю сего происшествия:

disk.addltemListener(new SomeltemEventHandler())

Сильно учащенно функционирования, записанные в группах меню, вызываются не едва щелчком кнопки мышки, но и "жгучими" клавишами-акселераторами (shortcut), воздействующими чаще целого при нажатой клавише <Ctrl>. На дисплее в этапах меню, которым назначены "пылкие" клавиши, являются подсказки типа Ctrl+N, Ctrl+O, как на рис. 13.1. "Обжигающая" клавиша определяется предметом сорта MenuShortcut и показывает в его конструкторе константой сорта KeyEvent, например:

MenuShortcut keyCreate = new MenuShortcut(KeyEvent.VK_N);

Спустя настоящего "нагретой" будет комбинация клавиш <Ctrl>+<N>. След полученный предмет показывает в конструкторе сорта Menuitem:

Menuitem create = new Menuitem("Создать", keyCreate);

Нажатие <Ctrl>+<N> будет будить окно составления. Настоящие воздействия, разумеется, можно соединить, например,

Menuitem open = new Menultern("Раскрыть...",

new -MenuShortcut(KeyEvent.VK_O));

Можно сложить снова нажатие клавиши <Shift>. Воздействие этапа меню будет вызываться нажатием комбинации клавиш <Shift>+<Ctrl>+<X>, если воспользоваться следующим конструктором:

MenuShortcut(int key, boolean useShift) 

Со доводом useShift == true.

Программа рисования, созданная в листинге 12.4 и показанная на рис. 12.3, безусловно перегружена кнопками. Перенесем их функционирования в этапы меню. Прибавим допустимость манипуляции файлами и группу завершения деятельности. Данное сделано в листинге 13.1. Сорт scribble не изменялся и в листинге не приведен. Итог показан на рис. 13.2.

Листинг 13.1. Программа рисования со меню 

import j ava.awt.*; 

import j ava.awt.event.*;

public class MenuScribble extends Frame{ 

public MenuScribble(String s) { super(s);

ScrollPane pane = new ScrollPane();

pane.setSize(300, 300);

add(pane, BorderLayout.CENTER);

Scribble scr = new Scribble(this, 500, 500); 

pane.add(scr);

MenuBar mb = new MenuBar(); 

setMenuBar(mb); 

Menu f = new Menu("Файл"); 

Menu v = new Menu("Вий"); 

mb.add(f); mb.add(v);

Menuitem open = new Menuitem("Раскрыть...",

new MenuShortcut(KeyEvent.VK_0));

Menuitem save = new Menuitem("Оставить",

new MenuShortcut(KeyEvent.VK_S));

Menuitem saveAs = new Menultera("Оставить как...");

Menuitem exit = new Menuitem("Выезд",

new MenuShortcut(KeyEvent.VK_Q));

f.add(open); f.add(save); f.add(saveAs);

f.addSeparator(); f.add(exit);

open.addActionListener(new ActionListener(){ 

public void actionPerformed(ActionEvent e){

FileDialog fd = new FileDialog(new Frame(),

" Загрузить", FileDialog.LOAD); 

fd.setVisible(true); 

});

saveAs.addActionListener(new ActionListener(){ 

public void actionPerformed(ActionEvent e){ 

FileDialog fd = new FileDialog(new Frame(),

" Оставить", FileDialog.SAVE); 

fd.setVisible(true); 

}

exit.addActionListener(new ActionListener(){ 

public void actionPerformed(ActionEvent e){

System.exit(0); 

}

});

Menu со = new Menu("Колер");

Menultem clear = new Menultem("Очистить",

new MenuShortcut(KeyEvent.VK_D)); 

v.add(c); v.add(clear);

Menultem red = new Menultem("Рубиновый"); 

Menultem green = new Menultem("Болотный"); 

Menultem blue = new Menultem("Лазурный"); 

Menultem black = new Menultem("Грустный"); 

c.add(red); c.add(green); c.add(blue); c.add(black);

red.addActionListener(scr);

green.addActionListener(scr);

blue.addActionListener(scr) ;

black.addActionListener(scr) ;

clear.addActionListener(scr) ;

addWindowListener(new WinClose()); pack();

setVisible(true) ; 

class WinClose extends WindowAdapter{

public void windowClosing(WindowEvent e){

System.exit(0); 

public static void main(String[] args){

new MenuScribble(" \"Малевать\" со меню"); 

}

Рис. 13.2. Программа рисования  со меню

Всплывающее меню

Всплывающее меню (popup menu) является просто при нажатии или отпускании справедливой или обычной кнопки мышки и появляется контекстным (context) меню. Его группы зависят от деталь, на котором жрать нажата кнопка мышки. В говоре Java всплывающее меню — предмет сорта Рорирмепи. Данный сорт расширяет сорт Menu, итак, руководствоваться целое свойства меню и этапа меню Menultem. Всплывающее меню присоединяется не к строчке меню сорта MenuBar или к меню сорта Menu в качестве подменю, а к определенному деталь. Для сего в сорте component жрать прием add(PopupMenu menu).

У неких компонентов, например TextFieid и TextArea, уже живет всплывающее меню. Сходственные меню неосуществимо переопределить.

Присоединить всплывающее меню можно лишь к одному деталь. Если надо использовать всплывающее меню со несколькими деталями в сосуде, то его присоединяют к сосуду, а желаемый деталей определяют со выручкой приема getcomponent () сорта MouseEvent, как показано в листинге 13.2.

Помимо унаследованных свойств и приемов, в сорте PopupMenu соль способ show (Component comp, int x, int у), показывающий всплывающее меню на дисплее так, что его левый наружный уголок располагается в точке (х, у) в подсистеме координат деталь сотр. Чаще целого сие деталей, на котором нажата кнопка мышки, возвращаемый способом getcomponent (). Деталей comp должен соль изнутри сосуда, к которому присоединено меню, иначе начнемся замечательная картина.

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

возникшее дело мышки поднимает возникновение всплывающего меню. Его нужно будить при появлении всевозможного дела мышки, чтобы проверять, не появляется ли оно знаком к возникновению всплывающего меню, т. е. воззванию к способу showo. Имелось бы излишне неловкий подсоединять таковую проверку в целое семь приемов классов-слушателей явлений мышки. Оттого прием IsPopupTrigger () лучше ВЫЗЫВНТЬ В способе processMouseEvent().

Переделаем вновь заодно программу рисования из листинга 12.4, введя в сорт scribble всплывающее меню для отбора колеры рисования и очистки окна и изменив обработку происшествий мышки. Для простоты спрятать строчку меню, хотя ее можно существо сохранить. Итог показан в листинге 13.2, а на рис. 13.3 — тип всплывающего меню в MS Windows.

Листинг 13.2. Программа рисования со всплывающим меню

import j ava.awt.* ; 

import j ava.awt.event.*;

public class PopupMenuScribble extends Frame{ 

public PopupMenuScribble(String s){ super (s) ;

ScrollPane pane = new ScrollPane(); 

pane.setSize(300, 300); 

add(pane, BorderLayout.CENTER);

Scribble scr = new Scribble(this, 500, 500); 

pane.add(scr);

addWindowListener(new WinClose()); 

pack ();

setVisible(true); 

class WinClose extends WindowAdapter{

public void windowClosing(WindowEvent e){

System.exit(0); 

public static void main(String[] args){

new PopupMenuScribble(" \"Малевать\" со всплывающим меню"); 

}

class ScriBble extends Component implements ActionListener{ 

protected int lastX, lastY, w, h; 

protected Color currColor = Color.black; 

protected Frame f;

protected PopupMenu c;

public Scribble(Frame frame, int width, int height)!{ 

f = frame; w = width; h = height; 

enableEvents(AWTEvent.MOUSE_EVENT_MASK | 

        AWTEvent.MOUSEJtoTIONJEVENT_MASK);

со = new PopupMenu ("Колер") ;

add(c);

Menultera clear = new Menultem("Очистить",

    new MenuShortcut(KeyEvent.VK_D)); 

Menultem red = new Menultem("Червонный"); 

Menultem green = new Menultem("Недозрелый"); 

Menultem blue = new Menultern("Лазурный"); 

Menultem black = new Menultem("Негритянский"); 

c.add(red); c.add(green); c.add(blue); 

c.add(black); со.addSeparator(); со.add(clear);

red.addActionListener(this); 

green.addActionListener(this); 

blue.addActionListener(this); 

black.addActionListener(this); 

clear.addActionListener(this); 

public Dimension getPreferredSize()

{

return new Dimension(w, h); 

}

public void actionPerformed(ActionEvent event){

String s = event.getActionCommand();

if (s.equals("Очистить")) repaint();

else if (s.equals("Червонный")) currColor = Color.red;

else if (s.equals("Болотный")) currColor = Color.green;

else if (s.equals("Сапфирный")) currColor = Color.blue;

else if (s.equals("Печальный")) currColor = Color.black; 

}

public void processMouseEvent(MouseEvent e){ 

if (e.isPopupTrigger())

c.show(e.getComponent (), e.getXO, e.getY()); 

else if (e.getlDO == MouseEvent.MOUSE_PRESSED){

lastX = e.getX(); lastY = e.getY(); }

else super.processMouseEvent(e); }

public void processMouseMotionEvent(MouseEvent e){ 

if (e.getlDO = MouseEvent.MOUSE_DRAGGED){ 

Graphics g = getGraphics();

g.setColor(currColor) ;

g.drawLinedastX, lastY, e.getX(), e.getY()); 

lastX = e.getX(); lastY = e.getY(); 

}

else super.processMouseMotionEvent(e); 

}

Рис. 13.3. Программа рисования  со всплывающим меню