Java. Полное руководство. 8-е издание. С. Н. Тригуб Перевод с английского и редакция
Скачать 25.04 Mb.
|
8 1 Рис. 25.1 Д. Аплет C a r d L a y o u t D e m o вовремя выполнения Общая процедура использования сеточной компоновки выглядит так. Сначала создается новый объект класса GridBagLayout, который определяется как текущий диспетчер компоновки. Затем выбираются ограничения для каждого компонента, добавляемого в сетку. После этого компоненты добавляются к диспетчеру компоновки. Хотя класс GridBagLayout является более сложным по сравнению с другими диспетчерами компоновки, использовать его будет очень легко, если вы хорошенько разберетесь с принципом его работы. Класс GridBagLayout определяет только один конструктор r i d B a g L a y o u t (Кроме того, этот класс определяет несколько методов, многие из которых являются защищенными и не предназначены для общего использования. Однако есть один метод, который следует использовать, — setConstraints (). void setConstraints(Component компаратор GridBagConstraints ограничения) Здесь параметр компаратор представляет компонент, к которому применяются ограничения, определяемые с помощью параметра ограничения Этот метод описывает ограничения, применяемые к каждому компоненту в сетке. Залогом успешного использования класса GridBagLayout является тщательная настройка его ограничений, которые хранятся в объекте класса GridBag Constraints. Класс GridBagConstraints определяет несколько полей, которые вы можете настроить для управления размерами, размещением и промежутками компонента. Эти поля перечислены в табл. 25.2. Некоторые из них будут описаны подробно немного позже 8 1 6 Часть II. Библиотека Таблица 25.2. Ограничительные поля, определяемые в классе GridBagConstraints Поле Назначение Задает местоположение компонента внутри ячейки. Значение по умолчанию — G r i d B a g C o n s t r a i n t Задает способ изменения размеров компонента, если размеры компонента меньше размеров его ячейки. Допустимыми являются значения GridBagConstraints .NONE (поумолчанию), G r i d B a g C o n s t r a i n t s .HORIZONTAL, G r i d B a g C o n s t r a i n t s . V ERTICAL и G r i d B a g C o n s t r a i n t s Задает высоту компонента в пересчете на ячейки. Значение по умолчанию — Задает ширину компонента в пересчете на ячейки. Значение по умолчанию — Задает координату X ячейки, в которую будет добавлен компонент. Значение по умолчанию — GridBagConstraints . Задает координату Y ячейки, в которую будет добавлен компонент. Значение по умолчанию — GridBagConstraints . Задает вставки. По умолчанию все вставки являются нулевыми Задает дополнительный горизонтальный промежуток, окружающий компонент внутри ячейки. Значение по умолчанию — О Задает дополнительный вертикальный промежуток, окружающий компонент внутри ячейки. Значение по умолчанию — О Задает весовое значение, которое определяет горизонтальные промежутки между ячейками и краями контейнера, в котором они содержатся. Значение по умолчанию — 0,0. Чем больше вес, тем больше будет промежуток. Если все значения будут равны 0 , 0, то дополнительные промежутки будут распределены равномерно между краями окна Задает весовое значение, которое определяет вертикальные промежутки между ячейками и краями контейнера, в котором они содержатся. Значение по умолчанию —0,0. Чем больше вес, тем больше будет промежуток. Если все значения будут равны 0 , 0 , то дополнительные промежутки будут распределены равномерно между краями окна Класс GridBagConstraints определяет также несколько статических полей, которые содержат стандартные значения ограничений, такие как значения GridBagConstraints.CENTER и Если размеры компонента меньше размеров его ячейки, можно воспользоваться полем anchor, чтобы определить, где внутри ячейки будет располагаться верхний левый угол компонента. Существует три типа значений, которые можно присвоить полю anchor. Первые являются абсолютными значениями anchor int fill int gridheight int gridwidth int gridx int gridy Insets insets int ipadx int ipady double weightx double weighty G r i d B a g C o n s t r a i n t s .CENTER G r i d B a g C o n s t r a i n t s .SOUTH G r i d B a g C o n s t r a i n t s .EAST G r i d B a g C o n s t r a i n t s .SOUTHEAST GridBagConstraints.NORTH G r i d B a g C o n s t r a i n t s .SOUTHWEST G r i d B a g C o n s t r a i n t s .NORTHEAST GridBagConstraints.WEST GridBagConstraints.NORTHWEST Глава 25. Использование элементов управления, диспетчеров компоновки. 8 1 Как можно судить по именам этих значений, они определяют расположение компонента в определенных местах. Второй тип значений, которые можно присвоить полю anchor, является относительным, те. относительно ориентации контейнера, которая в восточных языках может быть другой. Относительные значения перечислены ниже r i d B a g C o n s t r a i n t s .F I R S T _ L I N E _ E N D G r i d B a g C o n s t r a i n t s .L I N E _ E N D G r i d B a g C o n s t r a i n t s .F I R S T _ L I N E _ S T A R T G r i d B a g C o n s t r a i n t s .L I N E _ S T A R T G r i d B a g C o n s t r a i n t s .L A S T _ L I N E _ E N D G r i d B a g C o n s t r a i n t s .P A G E _ E N D G r i d B a g C o n s t r a i n t s .L A S T _ L I N E _ S T A R T G r i d B a g C o n s t r a i n t s .P A G E _ S T A R Их имена описывают расположение. Третий тип значений, которые могут быть присвоены полю anchor, позволяет позиционировать компоненты вертикально по отношению к базовой линии строки. Эти значения перечислены ниже r i d B a g C o n s t r a i n t s .B A S E L I N E G r i d B a g C o n s t r a i n t s .B A S E L I N E _ L E A D I N G G r i d B a g C o n s t r a i n t s .B A S E L I N E _ T R A I L I N G G r i d B a g C o n s t r a i n t s .A B O V E _ B A S E L I N E G r i d B a g C o n s t r a i n t s .A B O V E _ B A S E L I N E _ L E A D I N G G r i d B a g C o n s t r a i n t s .A B O V E _ B A S E L I N E _ T R A I L I N G G r i d B a g C o n s t r a i n t s .B E L O W _ B A S E L I N E G r i d B a g C o n s t r a i n t s .B E L O W _ B A S E L I N E _ L E A D I N G G r i d B a g C o n s t r a i n t s .B E L O W _ B A S E L I N E _ T R A I L I N При горизонтальном положении центрирование может осуществляться по отношению или к переднему краю (LEADING), или к заднему Поля weightx и weighty являются достаточно важными и на первый взгляд кажутся довольно запутанными. Их значения определяют, сколько дополнительного пространства будет выделено внутри контейнера для каждой строки и каждого столбца. По умолчанию оба поля имеют нулевые значения. Если все значения в столбце и строке будут нулевыми, то дополнительный промежуток будет распределен равномерно между краями окна. Увеличивая вес, вы увеличите это распределение пространства строки или столбца пропорционально остальным строкам или столбцам. Самый лучший способ уяснить эти значения — поэкспериментировать сними на конкретном примере. С помощью переменной gridwidth можно задать ширину ячейки в пересчете на единицы ячейки (cell unit). По умолчанию эта переменная имеет значение Чтобы компонент использовал свободное пространство в строке, применяйте значение GridBagConstraints . REMAINDER. Чтобы компонент мог использовать предпоследнюю ячейку в строке, применяйте значение GridBagConstraints. RELATIVE. Ограничение gridheight работает точно также, нов вертикальном направлении. Можно определить значение заполнения, которое будет использоваться для увеличения минимального размера ячейки. Для горизонтального заполнения присвойте значение переменной ipadx. Для вертикального заполнения присвойте значение переменной Ниже показан пример, в котором класс GridBagLayout служит для демонстрации только что рассмотренного материала Демонстрация применения n t .*; import j a v a .a p p l e t .*; 8 1 8 Часть II. Библиотека Java /* */ public class GridBagDemo extends Applet implements ItemListener { String msg = ""; Checkbox winXP, w i n 7 , solaris, mac; public void in i t () { GridBagLayout gbag = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); setLayout(gbag); // Определяем флажки = new Checkbox("Windows XP", null, true); win7 = new Checkbox("Windows 7"); solaris = new Checkbox("Solaris"); mac = new Checkbox("Mac OS"); // Определяем сетку Первой строке задаем нулевой вес, используемый по умолчанию gbc.weightx = 1.0; // используем вес столбца 1 g b c .ipadx = 2 0 0 ; // заполняем на 200 единиц = new Insets(4, 4, 0, 0); // вставка чуть в стороне от левого верхнего угла gbc.anchor = GridBagConstraints.NORTHEAST; g b c .gridwidth = GridBagConstraints.RELATIVE; g b a g .setConstraints(winXP, g b c ); g b c .gridwidth = GridBagConstraints.REMAINDER; g b a g .setConstraints(win7, gbc); // Задаем второй строке вес 1. gbc.weighty = 1.0; g b c .gridwidth = GridBagConstraints.RELATIVE; g b a g .setConstraints(solaris, gbc); g b c .gridwidth = GridBagConstraints.REMAINDER; g b a g .setConstraints(mac, gbc); // Добавляем компоненты Регистрация на получение уведомлений о событиях элемента i n 7 .addltemListener(this); solaris.addltemListener(this); m a c .addltemListener(this); } // Перерисовка в случае изменения состояния флажка public void itemStateChanged(ItemEvent ie) { repaint(); } // Отображаем текущее состояние флажков public void paint(Graphics g) { msg = "Current state: "; // msg = "Текущее состояние "; g .drawString(msg, 6, 80); msg = " Windows XP: " + w i n X P .getState(); Глава 25. Использование элементов управления, диспетчеров компоновки. 8 1 9 g .drawString(msg, msg = " Windows 7; g .drawString(msg, msg = " Solaris: ' g .drawString(msg, msg = " Mac: " + m a c .getState() g .drawString(msg, 6, 160); } 100) ; + w i n 7 .getState() , 120) ; solaris.getState(' 140) ; Аплет GridBagDemo вовремя выполнения показан на рис. 25.15. A p p le t V ie w e r: G rid B a ... - П Н Appfet W Windows XP W Solaris Current state: Windows XP’ true Windows 7* true Solaris: true Mac: true P Windows 7 R iM a c OS Applet Рис. 25.15. Окно аплета В этой схеме компоновки флажки операционных систем размещаются в сетке 2x2. Каждая ячейка имеет заполнение 200. Каждый компонент вставляется рядом с верхним левым углом (в 4 единицах от него. Вес столбца составляет 1, благодаря чему любой дополнительный горизонтальный промежуток распределяется равномерно между столбцами. Первая строка использует вес по умолчанию, равный 0; вторая строка имеет вес 1. Это означает, что любой дополнительный вертикальный промежуток переносится во вторую строку. Класс GridBagLayout является очень мощным диспетчером компоновки. Стоит потратить некоторое время на его изучение и эксперименты с ним. После того как поймете, для каких целей предназначены различные настройки, сможете использовать класс GridBagLayout для расположения компонентов с высокой степенью точности. Полосы меню и меню Окно переднего плана может иметь связанную с ним полосу меню, которая отображает список пунктов меню верхнего уровня. Каждый пункт меню связан с выпадающим меню. Этот принцип реализован в библиотеке AWT с помощью классов MenuBar, Menu и Menu Item. В общем случае полоса меню состоит из одно 8 2 Часть II. Библиотека го или нескольких объектов класса Menu. Каждый объект класса Menu содержит список объектов класса Menu Item. Каждый объект класса Menu Item представляет то, что может выбрать пользователь. Поскольку класс Menu является подклассом класса Menu Item, можно создать иерархию вложенных подменю. Можно также включать отмечаемые пункты меню, которые являются пунктами меню типа CheckboxMenuItem; если пользователь щелкнет на таком пункте, рядом с ним появится отметка (в виде “галочки”). Чтобы создать полосу меню, сначала создайте экземпляр класса MenuBar. Этот класс определяет только конструктор, который используется по умолчанию. Затем создайте экземпляры класса Menu, которые будут определять варианты выбора, отображаемые в строке. Ниже показаны конструкторы класса Menu. M e n u () throws HeadlessException Menu(String имяПункта) throws HeadlessException Menu(String имяПункта, boolean удаляемый throws Здесь имяПункта представляет имя пункта меню. Если параметр удаляемый содержит значение t ruer меню можно удалять и очищать. В противном случае оно останется присоединенным к полосе меню. (Удаляемые меню зависят от реализации) Первый вариант создает пустое меню. Отдельные пункты меню имеют тип Menu Item. Он определяет следующие конструкторы) throws HeadlessException Menultem(String имяПункта) throws HeadlessException Menultem(String имяПункта, MenuShortcut клавишаДоступа) Здесь параметр имяПункта представляет имя, отображаемое вменю, а параметр клавишаДоступа — клавишу быстрого доступа для данного пункта меню. Пункт меню можно включить или отключить с помощью метода set Enabled (). void setEnabled(boolean флагРазреш ения) Если параметр флагРазрешения содержит значение true, пункт меню будет включена если false — отключен. Состояние пункта меню можно определить с помощью метода isEnabled (). boolean Метод isEnabled () возвращает значение true, если пункт меню, для которого он вызывается, является включенным. В противном случае он возвращает значение Изменить имя пункта меню можно с помощью метода set Label () . Текущее имя пункта меню можно узнать с помощью метода get Label () . Эти методы показаны далее setLabel(String новоеИмя) String Здесь параметр новоеИмя представляет новое имя вызываемого пункта меню. Метод getLabel () возвращает текущее имя. Создать отмечаемый пункт меню можно с помощью подкласса CheckboxMenu Item класса Menu Item. Он имеет следующие конструкторы) throws HeadlessException CheckboxMenuItem(String имяПункта) throws HeadlessException CheckboxMenuItem(String имяПункта, boolean вкл) throws Здесь имяПункта представляет имя, отображаемое вменю. Отмечаемые пункты меню подобны триггеру (со счетным входом. Каждый раз, когда напротив одного из пунктов ставится отметка, его состояние изменяется. В первых двух формах отмечаемое полене имеет метки. В третьей форме, если параметр вкл содержит значение true, отмечаемое поле имеет метку. В противном случае оно остается пустым Глава 25. Использование элементов управления, диспетчеров компоновки. 8 2 Состояние отмечаемого пункта меню можно узнать с помощью метода get- State(). Присвоить ему определенное состояние можно при помощи метода set State () . Эти методы показаны ниже getState() void setState(boolean вкл) Если пункт меню отмечен, метод getState () возвращает значение true. В противном случае он возвращает значение false. Чтобы отметить пункт меню, передайте значение true методу setState(). Для очистки пункта меню передайте значение После того как создадите пункт меню, необходимо добавить его в объект класса Menu с помощью метода add () , который имеет следующую общую форму add(MenuItem пункт) Здесь пункт представляет добавляемый пункт меню. Добавление пунктов вменю производится в том порядке, в каком осуществлялись вызовы метода add () . Возвращаемым значением является пункт. После того как добавите все пункты в объект класса Menu, его можно будет добавить в полосу меню с помощью следующей версии метода add () , определенной в классе MenuBar. Menu add(Menu меню) Здесь параметр меню представляет добавляемое меню. Возвращаемым значением является меню. События вменю происходят только при выборе пункта типа Menultem и CheckboxMenuItem. Они не происходят, например, при обращении к полосе меню для отображения выпадающего меню. Каждый раз при выборе пункта меню создается объект класса ActionEvent. По умолчанию строка команды действия представляет собой имя элемента меню. Однако вы можете определить другую строку команды действия, вызвав метод set Act ionCommand () в элементе меню. Каждый раз, когда отмечается пункт меню или снимается отметка с него, создается объект класса ItemEvent. Таким образом, для обработки этих событий меню необходимо реализовать интерфейсы ActionListener и Метод get Item () класса ItemEvent возвращает ссылку на пункт меню, известивший о данном событии. Ниже показана общая форма этого метода Ниже представлен пример, который добавляет серию вложенных меню во всплывающее меню. В окне отображается выбранный пункт меню. Кроме того, отображается также состояние двух пунктов меню флажков Пример работы сменю Создаем подкласс Frame, class MenuFrame extends Frame { String msg = ""; CheckboxMenuItem debug, test; MenuFrame(String title) { super(title); // Создание полосы меню и добавление ее в фрейм 8 2 2 Часть II. Библиотека Java MenuBar mbar = new Men u B a r (); setMenuBar(mbar); // создание элементов меню Menu file = new M e n u ("File"); Menultem iteml, item2, item3, item4/ item5; file.a d d (iteml = new Menultem(" N e w . ; file.a d d (item2 = new Menultem("Open...")); file.a d d (item3 = new Menultem("Close")); file.add(item4 = new M e n u l t e m ; file.a d d (item5 = new Menultem(" Q u i t ; m b a r .add(file); Menu edit = new M e n u ("Edit"); Menultem item6, item7, item8, item9; e d i t .add(item6 = new Menultem("Cut")); e d i t .add(item7 = new Menultem("Copy")); e d i t .a d d (item8 = new Menultem("Paste")); e d i t .add(item9 = new Menultem("-")); Menu sub = new M e n u ("Special"); Menultem itemlO, itemll, iteml2; s u b .a d d (iteml0 = new Menultem("First")); sub.add(itemll = new Menultem("Second")) ; s u b .a d d (iteml2 = new Menultem("Third")); e dit.add(sub); // отмечаемые элементы меню = new CheckboxMenuItem("Debug"); ed i t .add(debug); test = new CheckboxMenuItem("Testing"); e dit.add(test); m b a r .a d d (edit); // создание объекта для обработки событий действия и элемента MyMenuHandler handler = new MyMenuHandler(this); // регистрируем объект на получение уведомлений об этих событиях t e m 6 .addAc t i onL i s t e n e r (handler); item7.addActionListener(handler); item8.addActionListener(handler); item9.addActionListener(handler); itemlO.addActionListener(handler); itemll.addActionListener(handler); iteml2.addActionListener(handler); d e bug.addltemListener(handler); t e s t .addltemListener(handler); // создание объекта для обработки событий окна MyWindowAdapter adapter = new MyWindowAdapter(this); // регистрируем объект на получение уведомлений об этих событиях addWindowListener(adapter); } public void paint(Graphics g) { g.drawString(msg, 10, 200); if(debug.getState()) Глава 25. Использование элементов управления, диспетчеров компоновки. 8 2 3 } g .drawString("Debug is on.", 10, 220); else g .drawString("Debug is off.", 10, 220); if(test.getState() ) g .drawString("Testing is on.", 10, 240); else g .drawString("Testing is off.", 10, 240), } class MyWindowAdapter extends WindowAdapter { MenuFrame menuFrame; public MyWindowAdapter(MenuFrame menuFrame) { this.menuFrame = menuFrame; } } public void windowClosing(WindowEvent we) { menuFrame.setVisible(false); } class MyMenuHandler implements ActionListener, ItemListener { MenuFrame menuFrame; public MyMenuHandler(MenuFrame menuFrame) { this.menuFrame = menuFrame; } // Обработка событий действий void actionPerformed(ActionEvent ae) { String msg = "You selected "; String arg = a e .getActionCommand(); if(arg.equals("New...")) msg + = "New."; else if(arg.equals("Open...")) msg += "Open."; else if(arg.equals("Close")) msg += "Close."; else if(arg.equals("Quit...")) msg += "Quit."; else if(arg.equals("Edit")) msg + = "Edit."; else if(arg.equals("Cut")) msg += "Cut."; else if(arg.equals("Copy")) msg + = "Copy."; else if(arg.equals("Paste") ; msg + = "Paste."; else if(arg.equals("First") msg += "First."; else if(arg.equals("Second")) msg += "Second."; else if(arg.equals("Third") ; msg += "Third."; else if(arg.equals("Debug") msg += "Debug."; else if(arg.equals("Testing")) msg += "Testing."; menuFrame.msg = msg; menuFrame.repaint(); } // Обработка событий элемента void itemStateChanged(ItemEvent ie) { menuFrame.repaint(); } } 8 2 4 Часть II. Библиотека Java // Создание обрамляющего окна public class MenuDemo extends Applet { Frame f ; public void init() { f = new MenuFrame("Menu Demo"); int width = Integer.parselnt(getParameter("width")); int height = Integer.parselnt(getParameter("height")) setSize(new Dimension(width, height)); } f .setSize(width, height); f .setVisible(true); public void start() { f .setVisible(true); } public void s t o p O { f .setVisible(false) , Аплет MenuDemo вовремя выполнения показан на рис. Рис. 25.16. Окно аплета Существует еще один класс, обслуживающий меню, который вас может заинтересовать, — класс PopupMenu. Он работает подобно классу Menu, но формирует меню, которое отображается в определенном месте. Класс PopupMenu контекстное меню) предлагает гибкую и полезную альтернативу некоторым типам организации меню. Диалоговые окна Довольно часто возникает необходимость в диалоговом окне для хранения набора связанных между собой элементов управления. Диалоговые окна используются, в первую очередь, для получения данных, вводимых пользователем. Нередко они Глава 25. Использование элементов управления, диспетчеров компоновки. 8 2 являются дочерними окнами в окне верхнего уровня. Диалоговые окна не имеют полос меню, однако в остальном они функционируют подобно обрамляющим окнам. (Например, вы можете добавлять в них элементы управления точно также, как добавляете их в обрамляющее окно) Диалоговые окна могут быть модальными или немодальными. Когда активным является модальное диалоговое окно, то все вводимые данные направляются в него до тех пор, пока оно остается открытым. Это значит, что вы не сможете обратиться к остальным частям своей программы до тех пор, пока не будет закрыто диалоговое окно. Если активным является немо дальное диалоговое окно, то фокус ввода может быть передан другому окну вашей программы. Таким образом, остальные части вашей программы остаются активными и доступными. Диалоговые окна имеют тип Dialog. Ниже показаны два наиболее часто используемых конструктора родит ельскоеО кн о boolean режим родит ельскоеО кно, String заголовок режим) Здесь параметр родит ельск о еО кн о представляет хозяина диалогового окна. Если параметр режим содержит значение true, диалоговое окно является модальным. В противном случае оно немодальное. Заголовок диалогового окна можно указать в параметре заголовок В общем случае выбудете организовывать подклассы класса Dialog, добавляя функциональные особенности, необходимые для вашего приложения. Ниже показан видоизмененный вариант предыдущей программы для работы сменю, в котором отображается немодальное диалоговое окно при выборе пункта меню N ew (Новое. Обратите внимание на то, что в момент закрытия диалогового окна вызывается метод dispose () . Этот метод определяется классом Window и освобождает все системные ресурсы, задействованные диалоговым окном Пример диалогового окна import j a v a .a w t .*; import j a v a .a w t .event.*; import java.applet.*; /* */ // Создание подкласса Dialog. class SampleDialog extends Dialog implements ActionListener { SampleDialog(Frame parent, String title) { super(parent, title, false); setLayout(new FlowLayout()); setSize(300, 200); add(new Label("Press this button:")); Button b; add(b = new B u tton("Cancel")); b.addActionListener(this); } public void actionPerformed(ActionEvent ae) { dispose(); } public void paint(Graphics g) { g .drawString("This is in the dialog box", 10, 70); } } // Создание подкласса Frame, class MenuFrame extends Frame { 8 2 Часть II. Библиотека Java String msg = CheckboxMenuItem debug, test; MenuFrame(String title) { super(title); // создание полосы меню и добавление ее во фрейм MenuBar mbar = new M e nuBar(); setMenuBar(mbar); // создание элементов меню Menu file = new M e n u ("File"); Menultem iteml, item2, item3, item4; file.a d d (iteml = new Menultem("New...")); file.a d d (item2 = new Menultem("Open...")); file.a d d (item3 = new Menultem("Close")); file.add(new Menultem("-")); file.a d d (item4 = new Menultem("Quit...")); m b a r .a d d (file); Menu edit = new M e n u ("Edit"); Menultem item5, item6, item7; edi t .a d d (item5 = new Menultem("Cut")); edi t .a d d (item6 = new Menultem("Copy")); edi t .a d d (item7 = new Menultem("Paste")); e d i t .add(new Menultem("-")); Menu sub = new M e n u ("Special", true); Menultem item8, item9, itemlO; s u b .a d d (item8 = new Menultem("First")); sub.add(item9 = new Menultem("Second")); sub.add(itemlO = new Menultem("Third")); e d i t .a d d (sub); // отмечаемые элементы меню = new CheckboxMenuItem("Debug"); edi t .a d d (debug); test = new CheckboxMenuItem("Testing"); e d i t .a d d (test); m b a r .add(edit); // создание объекта для обработки событий действия и элемента MyMenuHandler handler = new MyMenuHandler(this); // регистрация на получение уведомлений об этих событиях ebug.addltemListener(handler); test.addltemListener(handler); // создание объекта для обработки событий окна MyWindowAdapter adapter = new MyWindowAdapter(this); // регистрация на получение уведомлений об этих событиях addWindowListener(adapter); } public void paint(Graphics g) { Глава 25. Использование элементов управления, диспетчеров компоновки. 8 2 7 g .drawString(msg, 10, 200); if(debug.getState()) g .drawString("Debug is on.", 10, 220); else g .drawString("Debug is off.", 10, 220); if (test.getState()) g .drawString("Testing is on.", 10, 240); else g.drawString("Testing is off.", 10, 240); } } class MyWindowAdapter extends WindowAdapter { MenuFrame menuFrame; public MyWindowAdapter(MenuFrame menuFrame) { this.menuFrame = menuFrame; } ' public void windowClosing(WindowEvent we) { menuFrame.dispose() ; } class MyMenuHandler implements ActionListener, ItemListener { MenuFrame menuFrame; public MyMenuHandler(MenuFrame menuFrame) { this.menuFrame = menuFrame; } // Обработка событий действий void actionPerformed(ActionEvent ae) { String msg = "You selected "; String arg = a e .getActionCommand(); // Активизация диалогового окна при выборе пункта New. if(arg.equals("New...")) { msg += "New."; SampleDialog d = new SampleDialog(menuFrame, "New Dialog Box"); d.setVisible(true); } // Определяем остальные диалоговые окна для следующих пунктов else if(arg.equals("Open...")) msg += "Open."; else if(arg.equals("Close")) msg += "Close."; else if(arg.equals("Quit...")) msg += "Quit."; else if(arg.equals("Edit")) msg += "Edit."; else if(arg.equals("Cut")) msg + = "Cut."; else if(arg.equals("Copy")) msg += "Copy."; else if(arg.equals("Paste")) msg += "Paste."; else if(arg.equals("First")) msg += "First."; else if(arg.equals("Second")) msg += "Second."; else if(arg.equals("Third")) msg += "Third."; else if(arg.equals("Debug")) msg += "Debug."; else if(arg.equals("Testing")) msg += "Testing."; 8 2 8 Часть II. Библиотека Java menuFra m e . m s g = msg; m e n u F r a m e .r e p a i n t () ; } public voi d i t e m S t a t e C h a n g e d (ItemEvent ie) { m e n u F r a m e .r e p a i n t () ; } } // Создание обрамляющего окна class DialogDemo extends Applet { Frame f; public voi d init() { f = new M e n u F r a m e ("Menu Demo"); int w idth = I n t e g e r . p a r s e l n t ( g e t P a r a m e t e r (" w i d t h " )); int height = I n t e g e r .p a r s e l n t ( g e t P a r a m e t e r (" h e i g h t ")); s e t S i z e ( w i d t h , height); f .setSize(width, height); f .s e t V i s i b l e ( t r u e ) ; } public voi d s t a r t () { f .s e t V i s i b l e (t r u e ); i public voi d s t o p O { f .s e t V i s i b l e (f a l s e ) ; } } Аплет DialogDemo вовремя выполнения показан на рис. Совет. При желании можно попробовать определить диалоговые окна для других пунктов представляемых с помощью меню. К л асс Язык Java предлагает встроенное диалоговое окно, в котором пользователь может выбрать файл. Чтобы создать диалоговое окно выбора файла, реализуйте объект класса FileDialog. После этого будет отображено диалоговое окно выбора файла. Обычно оно представляет собой стандартное диалоговое окно выбора файла, используемое в операционной системе. Ниже показаны конструкторы класса FileDialog. FileDialog(Frame родительский заголовокО кн а родительский заголовок Окна как родит ельский) Здесь параметр родительский представляет владельца диалогового окна, а параметр заголовокОкна задает имя, отображаемое в строке заголовка диалогового окна. Если параметр заголовокОкна опустить, заголовок диалогового окна отображаться не будет. Если параметр как будет содержать значение FileDialog. LOAD, при выборе файла окно будет использоваться для чтения, а если значение Fi leDialog. SAVE — для записи. Если этот параметр опустить, окно будет использоваться при выборе файла для чтения Глава 25. Использование элементов управления, диспетчеров компоновки 2 9 Applet ' Applet start* мео у u em o ; Fite П .X You selected N Debug is off. Testing is off New Dialog Box ^ Press tJisbatonr [Ogrioisl This isintm йШщ Рис. 25.17. Аплет DialogDemo вовремя выполнения Класс FileDialog предлагает методы, позволяющие определять имя файла и его путь, после того как этот файл будет выбран пользователем. Ниже показано два примера этих методов getDirectory() String Эти методы возвращают, соответственно, каталоги имя файла. В следующей программе активизируется стандартное диалоговое окно выбора файла Пример диалогового окна выбора файла. Это — приложение а не аплет. */ import j a v a .a w t .*; import j a v a .a w t .event.*; // Создание подкласса Frame, class SampleFrame extends Frame { SampleFrame(String title) { super(title); // удаление окна после его закрытия addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { System.exit(0)? }) ; } ) 8 3 0 Часть II. Библиотека Java // Пример FileDialog.' class FileDialogDemo { public static void main(String a r g s []) { // создание фрейма, которому будет принадлежать диалоговое окно Frame f = new SampleFrame("File Dialog Demo"); f .setVisible(true) ; f .setSize(100, 100); FileDialog fd = new FileDialog(f , "File Dialog"); На рис. 25.18 можно видеть результат выполнения этой программы. (Точная конфигурация диалогового окна может быть иной.) г-1 Д , - File Г Ж. Ош n- l f ga1aDotetviewer □javaw □orbd j ЦЗ AppWindow .class ^pjavaws □pack200 My Recent IQapt □jconsole packager Documents i beanreg.dll □)db □poficytool 0 Qextcheck □jps formic .S| FileDialogDemo. dass □jstat □rmid Desktop QHtmlConverter □jstatd □rrmregistry tadj □keytool j s j j SampleFrame.dass J □jar □kimt Qseridver Qjarstgner □khst □servertool My Documents '□java □ktab □tnameserv tQjavac Isj MyKeyAdapter. dass 3unpack200 My Computer Qjavadoc ! g3j MyMouseAdapter Щ MyWindowAdapter. dass Qnative2asci 4 f ----------------------- --- _ . --------------, My Network Places Rename j j jrj | ЙР» | Fiesof type. | AH Files fx) .1 Cancel Рис. 25.18. Программа, в которой используется диалоговое окно выбора файла, вовремя выполнения Последний момент начиная cJDK 7 вы можете использовать класс Fi leDialog для выбора в списке файлов. Эти функциональные возможности обеспечивают методы setMultipleMode(), isMultipleMode( ) и Обработка событий при расширении компонентов библиотеки Модель делегирования событий была описана в главе 23, и во всех предыдущих программах из этой книги использовалась именно она. Однако в Java события можно также обрабатывать за счет организации подклассов компонентов библиотеки AWT. При таком подходе можно обрабатывать события почти также, как если бы они обрабатывались под управлением исходной версии Java 1.0. Естественно, что такой подход не рекомендуется, поскольку он имеет fe же недостатки, что и модель событий в Java 1.0, среди которых главным является неэффективность. Обработка событий за счет расширения компонентов библиотеки AWT описывается в настоящем разделе для полноты рассмотрения материала. Однако в остальных разделах этой книги данный подход не используется. При расширении компонента AWT необходимо вызывать метод enableEvents () класса Component. Он имеет следующую общую форму final void enableEvents(long маскаСобытия) Параметр маска События представляет битовую маску, определяющую событие, которое необходимо направить этому компоненту. Для формирования маски класс AWTEvent определяет константы int. Ниже перечислены некоторые из них. |