Java — Как скрыть label при нажатии на любую область окна программы


Содержание

Занятие 10

Обработка событий в Swing

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

Таким образом, при разработке программы необходимо:

  1. Выявить события, в ответ на которые потребуется реакция программы.
  2. Написать код, реализующий эту реакцию (так называемый обработчик событий).
  3. Связать обработчик события с соответствующим событием.

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

Паттерн проектирования «наблюдатель»

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

В библиотеке Swing для привязки обработчика события к вызывающему его компоненту используется паттерн проектирования «наблюдатель».

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

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

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

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

Заметим, что в данной схеме один наблюдатель может быть зарегистрирован у нескольких объектов (т.е. одинаково реагировать на изменения в каждом из них), а у одного объекта может быть несколько наблюдателей (т.е. при возникновении события выполняется несколько независимых методов-обработчиков). Это весьма увеличивает гибкость программирования.

Механизм обработки событий библиотеки Swing

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

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

Интерфейс MouseListener и обработка событий от мыши

Мы рассмотрим технологию написания слушателей на примере слушателей событий мыши.

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

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

Слушатель событий от мыши должен реализовать интерфейс MouseListener. В этом интерфейсе перечислены следующие методы:

public void mouseClicked(MouseEvent event) — выполнен щелчок мышкой на наблюдаемом объекте

public void mouseEntered(MouseEvent event) — курсор мыши вошел в область наблюдаемого объекта

public void mouseExited(MouseEvent event) — курсор мыши вышел из области наблюдаемого объекта

public void mousePressed(MouseEvent event) — кнопка мыши нажата в момент, когда курсор находится над наблюдаемым объектом

public void mouseReleased(MouseEvent event) — кнопка мыши отпущена в момент, когда курсор находится над наблюдаемым объектом

Каждый из этих методов получает параметр типа MouseEvent , через который передается дополнительная информация о возникшем событии. Например, можно получить объект, вызвавший данное событие, командой event.getSource() (не забывайте, что один и тот же слушатель может быть зарегистрирован в нескольких объектах и иногда ему может понадобиться узнать, какой именно из них вызвал данный метод). Метод getPoint() вернет координаты точки, в которой находился курсор мыши, когда было инициировано событие. Метод getClickCount() возвращает число сделанных подряд щелчков (имеет смысл только для mouseClicked() и позволяет особым образом обработать двойной, тройной и т.п. щелчок).

Чтобы обработать нажатие на кнопку, требуется описать класс, реализующий интерфейс MouseListener , причем метод mouseClicked() должен содержать обработчик события. Далее необходимо создать объект этого класса и зарегистрировать его как слушателя интересующей нас кнопки. Для регистрации слушателя используется метод addMouseListener(MouseListener listener) .

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

class MouseL implements MouseListener < public void mouseClicked(MouseEvent event) < if (loginField.getText().equals( "Иван" )) JOptionPane.showMessageDialog( null , "Вход выполнен" ); else JOptionPane.showMessageDialog( null , "Вход НЕ выполнен" ); >public void mouseEntered(MouseEvent event) <> public void mouseExited(MouseEvent event) <> public void mousePressed(MouseEvent event) <> public void mouseReleased(MouseEvent event) <> >

Мы сделали слушателя вложенным классом класса SimpleWindow , чтобы он мог легко получить доступ к его внутренним полям loginField и passwordField . Кроме того, хотя реально мы обрабатываем только одно из пяти возможных событий мыши, описывать пришлось все пять методов (четыре имеют пустую реализацию). Дело в том, что в противном случае класс пришлось бы объявить абстрактным (ведь он унаследовал от интерфейса пустые заголовки методов) и мы не смогли бы создать объект этого класса. А мы должны создать объект слушателя и прикрепить его к кнопке. Для этого в код конструктора SimpleWindow() необходимо добавить команду:

ok.addMouseListener( new MouseL());

Это можно сделать сразу после команды:

JButton ok = new JButton( «OK» );

Создание слушателей с помощью анонимных классов

Чтобы кнопка ok обрела слушателя, который будет обрабатывать нажатие на нее, нам понадобилось описать новый (вложенный) класс. Иногда вместо вложенного класса можно обойтись анонимным. Как вы помните, анонимный класс не имеет имени и в программе может быть создан только один объект этого класса (создание которого совмещено с определением класса). Но очень часто, как и в нашем примере, слушатель пишется для того, чтобы обрабатывать события единственного объекта — в нашем случае кнопки ok , а значит, используется в программе только однажды: во время привязки к этому объекту. Таким образом, мы можем заменить вложенный класс анонимным. Для этого описание класса MouseL можно просто удалить, а команду

ok.addMouseListener( new MouseL());

ok.addMouseListener( new MouseListener() < public void mouseClicked(MouseEvent event) < if (loginField.getText().equals( "Иван" )) JOptionPane.showMessageDialog( null , "Вход выполнен" ); else JOptionPane.showMessageDialog( null , "Вход НЕ выполнен" ); >public void mouseEntered(MouseEvent event) <> public void mouseExited(MouseEvent event) <> public void mousePressed(MouseEvent event) <> public void mouseReleased(MouseEvent event) <> >);

Новый вариант выглядит более громоздко, чем первый. Злоупотребление анонимными классами может сделать программу плохо читаемой. Однако в результате все действия с кнопкой (создание, настройка ее внешнего вида и команды обработки щелчка по ней) не разнесены, как в случае вложенных классов, а находятся рядом, что облегчает сопровождение (внесение изменений) программы. В случае простых (в несколько строк) обработчиков разумно делать выбор в пользу анонимных классов.

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

Класс MouseAdapter

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

Класс MouseAdapter реализует интерфейс MouseListener , определяя пустые реализации для каждого из его методов. Можно унаследовать своего слушателя от этого класса и переопределить те методы, которые нам нужны.

В результате предыдущее описание слушателя будет выглядеть более компактно:

Общая структура слушателей

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

Каждый слушатель должен реализовывать интерфейс ***Listener , где *** — тип слушателя. Практически каждому из этих интерфейсов (за исключением тех, в которых всего один метод) соответствует пустой класс-заглушка ***Adapter . Каждый метод интерфейса слушателя принимает один параметр типа ***Event , в котором собрана вся информация, относящаяся к событию. Мы не будем подробно рассматривать методы получения этой информации. Как правило их немного и их назначение легко понять, а перечень методов даст контекстная подсказка Eclipse.

Чтобы привязать слушателя к объекту (который поддерживает соответствующий тип слушателей) используется метод add***Listener(***Listener listener) .

Например, слушатель MouseListener должен реализовать интерфейс с таким же именем, которому соответствует класс-заглушка MouseAdapter . Методы этого интерфейса обрабатывают параметр типа MouseEvent , а регистрируется слушатель методом addMouseListener(MouseListener listener) . Мы не будем повторять эту информацию для других типов слушателей, они работают аналогично.

Слушатель фокуса FocusListener

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

Интерфейс FocusListener имеет два метода:

public void focusGained(FocusEvent event) — вызывается, когда наблюдаемый объект получает фокус

public void focusLost(FocusEvent event) — вызывается, когда наблюдаемый объект теряет фокус.

Слушатель колесика мышки MouseWheelListener

Слушатель MouseWheelListener оповещается при вращении колесика мыши в тот момент, когда данный компонент находится в фокусе. Этот интерфейс содержит всего один метод:

public void mouseWheelMoved(MouseWheelEvent event) .

Слушатель клавиатуры KeyListener

Слушатель KeyListener оповещается, когда пользователь работает с клавиатурой в тот момент, когда данный компонент находится в фокусе. В интерфейсе определены методы:

public void mouseKeyTyped(KeyEvent event) — вызывается, когда с клавиатуры вводится символ

public void mouseKeyPressed(KeyEvent event) — вызывается, когда нажата клавиша клавиатуры

public void mouseKeyReleased(KeyEvent event) — вызывается, когда отпущена клавиша клавиатуры.

Аргумент event этих методов способен дать весьма ценные сведения. В частности, команда event.getKeyChar() возвращает символ типа char , связанный с нажатой клавишей. Если с нажатой клавишей не связан никакой символ, возвращается константа CHAR_UNDEFINED . Команда event.getKeyCode() возвратит код нажатой клавиши в виде целого числа типа int . Его можно сравнить с одной из многочисленных констант, определенных в классе KeyEvent : VK_F1 , VK_SHIFT , VK_D , VK_MINUS и т.д. Методы isAltDown() , isControlDown() , isShiftDown() позволяют узнать, не была ли одновременно нажата одна из клавиш-модификаторов Alt, Ctrl или Shift.

Упражнение.

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

Слушатель изменения состояния ChangeListener

Слушатель ChangeListener реагирует на изменение состояния объекта. Каждый элемент управления по своему определяет понятие «изменение состояния». Например, для панели со вкладками JTabbedPane это переход на другую вкладку, для ползунка JSlider — изменение его положения, кнопка JButton рассматривает как смену состояния щелчок на ней. Таким образом, хотя событие это достаточно общее, необходимо уточнять его специфику для каждого конкретного компонента. В интерфейсе определен всего один метод:

public void stateChanged(ChangeEvent event) .

Слушатель событий окна WindowListener

Слушатель WindowListener может быть привязан только к окну и оповещается о различных событиях, произошедших с окном:

public void windowOpened(WindowEvent event) — окно открылось.

public void windowClosing(WindowEvent event) — попытка закрытия окна (например, пользователя нажал на крестик). Слово «попытка» означает, что данный метод вызовется до того, как окно будет закрыто и может воспрепятствовать этому (например, вывести диалог типа «Вы уверены?» и отменить закрытие окна, если пользователь выберет «Нет»).

public void windowClosed(WindowEvent event) — окно закрылось.

public void windowIconified(WindowEvent event) — окно свернуто.

public void windowDeiconified(WindowEvent event) — окно развернуто.

public void windowActivated(WindowEvent event) — окно стало активным.

public void windowDeactivated(WindowEvent event) — окно стало неактивным.

Слушатель событий компонента СomponentListener


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

public void componentMoved(ComponentEvent event) — вызывается, когда наблюдаемый компонент перемещается (в результате вызова команды setLocation() , работы менеджера размещения или еще по какой-то причине).

public void componentResized(ComponentEvent event) — вызывается, когда изменяются размеры наблюдаемого компонента.

public void componentHidden(ComponentEvent event) — вызывается, когда компонент становится невидимым.

public void componentShown(ComponentEvent event) — вызывается, когда компонент становится видимым.

Слушатель выбора элемента ItemListener

Слушатель ItemListener реагирует на изменение состояния одного из элементов, входящих в состав наблюдаемого компонента. Например, выпадающий список JComboBox состоит из множества элементов и слушатель реагирует, когда изменяется выбранный элемент. Также данный слушатель оповещается при выборе либо отмене выбора флажка JCheckBox или переключателя JRadioButton , изменении состояния кнопки JToggleButton и т.д. Слушатель обладает одним методом:

public void itemStateChanged(ItemEvent event) .

Универсальный слушатель ActionListener

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

Для отслеживания и обработки такого события может быть использован особый слушатель ActionListener , имеющий один метод:

public void actionPerformed(ActionEvent event) .

У использования ActionListener есть небольшое преимущество в эффективности (так, при обработке нажатия на кнопку не надо реагировать на четыре лишних события — ведь даже если методы-обработчики пустые, на вызов этих методов все равно тратятся ресурсы). А кроме того очень удобно запомнить и постоянно использовать один класс с одним методам и обращаться к остальным лишь в тех относительно редких случаях, когда возникнет такая необходимость.

Обработка нажатия на кнопку ok в нашем примере легко переписывается для ActionListener:

Работа с меню в библиотеке Swing

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

Создание главного меню

Главное меню окна представлено в Swing классом JMenuBar . По сути своей этот класс представляет собой панель с менеджером расположения BoxLayout (по горизонтали), в которую можно добавлять не только элементы меню, но и что угодно: хоть выпадающие списки, хоть панели с закладками. Однако для удобства пользования программой предпочтительнее использовать «традиционные» возможности меню.

Главное меню должно быть присоединено к окну методом setJMenuBar(JMenuBar menuBar) .

Элементами главного меню являются обычные меню — выпадающие прямоугольные блоки команд — объекты класса JMenu . Конструктор JMenu(String title) принимает один параметр: название меню, которое будет отображаться в строке главного меню. *

Меню, в свою очередь, состоит из пунктов меню, представленных классом JMenuItem . По логике работы пункты меню аналогичны кнопке JButton , то есть, при нажатии на него пользователем выполняется какое-то действие.

У класса JMenuItem есть наследники. Класс JCheckBoxMenuItem по логике работы аналогичен флажку JCheckBox — то есть, прямо в меню можно установить или сбросить какой-либо параметр логического типа. Класс JRadioButtonMenuItem эмулирует переключатель, позволяя выбрать только одну из нескольких альтернатив.

Создать элемент меню можно пустым конструктором JMenuItem либо (что более востребовано) одним из конструкторов, в которые передается текст и/или значок элемента меню: JMenuItem(String text) , JMenuItem(Icon icon) , JMenuItem(String text, Icon icon) . Конечно, в любой момент текст и значок можно сменить методами setText(String text) и setIcon(Icon icon) соответственно.

Цукерберг рекомендует:  Как создать VR-приложение

Элемент добавляется в меню методом add(JMenuItem item) класса JMenu . Чтобы отделить группы взаимосвязанных элементов меню, можно добавить между ними разделитель методом addSeparator() класса JMenu .

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

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

Обработка команд меню

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

fileMenu.add( new JMenuItem( «Выйти» ));

на последовательность команд:

JMenuItem exit = new JMenuItem( «Выйти» ); exit.addActionListener( new ActionListener() < public void actionPerformed(ActionEvent event) < System.exit(0); >>); fileMenu.add(exit);

Командой System.exit(0) прекращается работа текущего приложения.

Создание контекстного меню

Контекстное (или всплывающее) меню реализовано в классе JPopupMenu , очень похожему на класс JMenu . Отличительным методом этого класса является метод show(Component comp, int x, int y) , отображающий меню в точке с заданными координатами относительно границ заданного компонента.

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

Рассмотрим пример, в котором к уже созданному нами окну добавляется метка с надписью и контекстное меню из двух элементов, связанное с этой меткой. Необходимо добавить в конструктор перед последней командой ( setSize ) следующий код:

label = new JLabel( «КНИЖКА» , new ImageIcon( «1.gif» ), JLabel.RIGHT); JPanel panel = new JPanel(); panel.add(label); popup = new JPopupMenu(); popup.add( new JMenuItem( «Прочитать» )); popup.add( new JMenuItem( «Сжечь» )); label.addMouseListener( new MouseAdapter() < public void mouseClicked(MouseEvent event) < if (SwingUtilities.isRightMouseButton(event)) popup.show(label, event.getX(), event.getY()); >>); setContentPane(panel);

При этом в определении класса окна следует ввести два поля:

JPopupMenu popup; JLabel label;

Это необходимо для того, чтобы анонимный класс-слушатель мог обратиться к метке и к контекстному меню.

Приведенный пример также иллюстрирует применение полезного метода isRightMouseButton(MouseEvent event) , определенного в классе вспомогательных утилит SwingUtilities . Метод получает информацию о событии мыши и отвечает на вопрос, была ли нажата именно правая кнопка мыши. Методы getX() и getY() возвращают координаты курсора мыши относительно наблюдаемого компонента.

Интерфейс Action (действие) и класс AbstractAction

Очень часто одна и та же команда дублируется в графическом интерфейсе в нескольких местах. Например, команда «Копировать» может присутствовать в главном меню окна, в контекстном меню некоторого объекта, а также в виде кнопки на инструментальной панели. Это необходимо для удобства пользования программой. Однако, привязывать ко всем этим объектам (кнопкам и командам меню) одинаковых слушателей довольно утомительно. Более того, все эти команды одинаково должны реагировать на изменения состояния программы: если копирование по каким-то причинам становится невозможным, то все элементы управления, представляющие данную команду, должны сделаться неактивными.

Для упрощения работы в таких ситуациях предусмотрен интерфейс Action . Он собирает в одном месте все, что относится к некоторому действию: обработчик, показатель активности, всплывающую подсказку, значок и т.д.

Интерфейс Action унаследован от интерфейса ActionListener , поэтому его главный метод — actionPerformed(ActionEvent event) . Именно здесь программируется само действие. Но помимо этого посредством метода putValue(String key, Object value) можно задать одно из дополнительных свойств действия. Первый параметр — строковый идентификатор свойства. Он может принимать одно из значений, описанных в константах интерфейса Action . Второй параметр — объект, представляющий собой значение свойства.

Основные свойства интерфейса Action (точнее, соответствующие им константы):

NAME — имя действия,

SMALL_ICON — значок, соответствующий действию,

SHORT_DESCRIPTION — краткое описание действия (для всплывающей подсказки).

Метод setEnabled(boolean enabled) позволяет сделать действие активным или неактивным.

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

Недостаток интерфейса Action — в нем слишком много вспомогательных абстрактных методов (их семь, в том числе setEnabled() и putValue() ) и программировать их достаточно утомительно. Поэтому обычно используется реализующий данный интерфейс класс AbstractAction , в котором «не заполнен» единственный метод — actionPerformed() , а его все равно необходимо определить для программирования сути действия.

Здесь в окне описаны два внутренних класса-действия, одно из которых — это выход из программы. Объект этого класса, exitAction, является внутренним полем класса-окна и на его основе создается пункт меню и две кнопки. Второй класс-действие активирует и деактивирует объект exitAction (при этом изменяется соответствующий действию текст). Запустите пример и пронаблюдайте за тем, как выглядят и ведут себя объекты на основе Action , а затем внимательно проанализируйте его.

Стандартные диалоговые окна

Класс JOptionPane

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

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

Метод showMessageDialog() выводит на экран диалоговое окно, информирующее пользователя. Оно содержит надпись, значок и кнопку ОК. Существует несколько разновидностей этого метода с разными наборами параметров. Самый простой из них showMessageDialog(Component component, Object content) требует указания компонента, над которым должно появиться диалоговое окно и содержимого окна. Чаще всего содержимым окна является некоторая строка, а вместо первого параметра передается null — тогда окно появляется по центру экрана. Более «продвинутый» вариант showMessageDialog(Component component, Object content, String title, int type) позволяет задать также свой заголовок окна и выбрать его тип (влияет на иконку в окне): сообщение об ошибке ( ERROR_MESSAGE ), предупреждение ( WARNING_MESSAGE ), информация ( INFORMATION_MESSAGE ).

Диалоговое окно является модальным. Это значит, что пока пользователь не нажмет в этом окне кнопку OK, программа окажется заблокирована — пользователь не сможет работать с другими окнами.

Пронаблюдаем действие метода на простом примере:

Кнопка button сделана полем класса окна, чтобы можно было получить к ней доступ из анонимного класса-слушателя.

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

Данное окно отображается методом showConfirmDialog(Component component, Object content) . Параметры этого метода идентичны по смыслу параметрам showMessageDialog() , но в диалоговом окне появится не одна кнопка, а три: «Yes», «No» и «Cancel». Более того, метод возвращает значение, которое можно сравнить с константами YES_OPTION , NO_OPTION и CANCEL_OPTION . Логику работы с этим методом проиллюстрирует пример:

Метод имеет еще четыре разновидности с разным набором параметров, позволяющих изменять заголовок и значок окна, а также набор кнопок.

Класс JFileChooser

Swing содержит готовое окно для выбора файла (полезное, например, для программирования пункта меню Файл Открыть). Объект класса JFileChooser создается простым конструктором без параметров, после чего может выводиться на экран методом showOpenDialog() . Этот метод возвращает результат действий пользователя по выбору файла, который сравнивается с одной из следующих констант:

APPROVE_OPTION — выбор файла прошел успешно. Теперь можно методом getFile() получить выбранный файл.

CANCEL_OPTION — пользователь отменил выбор файла, щелкнув на кнопке Cancel.

ERROR_OPTION — при выборе файла произошла ошибка, либо пользователь закрыл диалоговое окно крестиком.

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

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

Метод setDialogTitle(String title) позволяет задать окну заголовок.

Dobrovoi Master

Раскрывающиеся блоки с скрытым содержанием с помощью CSS3

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

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

Давайте, постараемся обойтись без лишней воды, посмотрите весь этот простейший механизм в действии, на наглядном примере, так же можете и подредактировать что-нибудь при желании:

Пример №1

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

Как видите всё более-чем прекрасно работает, скрытое содержание, как появляется без проблем, так и исчезает от легкого нажатия мышкой, и при этом мы задействовали самый минимум исполняемого кода, и в html-каркасе, и в формировании стилей css. Без подключения дополнительных javascript библиотек, с извечной тревогой, а не отключены ли они на стороне пользователя.
Реализовать всё это действо, стало возможным благодаря CSS3 псевдоклассу :checked, применяемым к элементам интерфейса, таким как переключатели (checkbox). Что мы собственно и сделали, в теге атрибуту type мы присвоили значение checkbox , а так же идентификатор соответствующий уникальному идентификатору for=»hd-1″ переключателя текущего блока. Чекбоксы спрячем основательно и навсегда, прописав в классе .hide свойство display: none;
Собственно здесь, объяснять-то особо и нечего, весь механизм включения и выключения скрытых блоков состоит из трех элементов:


  • Флажок (Checkbox) — тег со значением checkbox атрибута type и с определённым связующим идентификатором
  • Заголовок (текст переключатель) — тег со значением уникального идентификатора для атрибута for, (идентификатор обязательно должен быть таким же, как идентификатор тега input со значением checkbox атрибута type).
  • Блок с содержимым — тег div , в котором и будет содержаться до лучших времен, пока пользователь не кликнет, различный скрытый контент (текст, изображения и т.д. и т.п.)

Надеюсь, из моего сумбурного пояснения, все же стало понятно в чём вся фишка. CSS применяет новые стили (с помощью псевдокласса checked), чтобы показать блок контента, который до этого был скрыт, только тогда, когда пользователь нажимает на элемент, который связан с флажком(checkbox) по уникальному идентификатору.

Из всего этого следует важное замечание:

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

Так, на словах мы разобрали, что куда и зачем, теперь, давайте посмотрим на html-каркас всей коннструкции:

Нажмите здесь, чтобы открыть!

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

1. CSS

/* скрываем чекбоксы и блоки с содержанием */ .hide, .hide + label

div < display: none; >/* вид текста label */ .hide + label, .hide:checked + label < padding: 0; color: green; cursor: pointer; border-bottom: 1px dotted green; >/* вид текста label при активном переключателе */ .hide:checked + label < color: red; border-bottom: 0; >/* когда чекбокс активен показываем блоки с содержанием */ .hide:checked + label + div

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

2. CSS

/* скрываем чекбоксы и блоки с содержанием */ .hide, .hide + label

По всем раскладам, способ несомненно хорош, но как всегда, даже не удивительно нисколько, проблемы возникают с вечным тормозом прогресса, браузером IE, псевдо-класс checked поддерживают только 9-я и более современные версии этого браузера. Для старых версий IE-шки, остаётся всё по-старому, вам придётся использовать javascript.

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

Буду признателен, если поделитесь ссылкой на запись в своих соц-сетях:

Блог только про Java

Учимся программировать на Java с нуля

Создание диалоговых окон в Java

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

На рис.1 показано типичное модальное диалоговое окно, содержащее сообщение. Подобное окно отображается на экране после того, как пользователь выбрал пункт меню About.

Для того чтобы реализовать такое окно, необходимо создать подкласс класса JDialog. По сути, это тот же процесс, которым мы воспользовались для создания главного окна приложения, расширяя класс JFrame.

Точнее говоря, нужно сделать следующее:

  1. В конструкторе вашего диалогового окна вызовите конструктор суперкласса JDialog. Добавьте в диалоговое окно компоненты пользовательского интерфейса.
  2. Добавьте обработчики событий.
  3. Задайте размер диалогового окна.

При вызове конструктора суперкласса нужно указать фрейм-владелец, заголовок окна и признак модальности.

Фрейм-владелец управляет местом отображения диалога. Вы можете указать null вместо владельца — тогда диалог будет принадлежать скрытому фрейму.

Признак модальности указывает на то, должны ли блокироваться другие окна вашего приложения, пока отображается диалог. Немодальные окна не блокируют другие окна.

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

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

Начиная с Java SE 6, добавлены два дополнительных типа модальности. Документо-модальный диалог блокирует все окна, относящиеся к одному «документу», или, точнее говоря, все окна с тем же родительским корневым окном, что и у данного диалога.

Это решает проблему систем помощи. В более старых версиях пользователи не могли взаимодействовать с окнами справки, когда всплыли модальный диалог. Toolkit-модальный диалог блокирует все окна их одного и того же «toolkit»(набора инструментов).

Toolkit — это программа Java, запускающая несколько приложений, такая как механизм аплетов в браузере. Дополнительную информацию на эту тему можно найти по адресу http://www.oracle.com/technetwork/java/index.html

Рис.1. Диалоговое окно About

Ниже приведен фрагмент программы, создающая диалоговое окно:

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

Для того чтобы отобразить диалоговое окно на экране, необходимо создать новый объект JDialog и вызвать метод setVisible():

Фактически в программе, рассматриваемой здесь в качестве примера, диалоговое окно создается только единожды, а затем мы используем его повторно каждый раз, когда пользователь щелкает на кнопке About:

Когда пользователь щелкает на кнопке ОК, диалоговое окно должно закрываться. Эта реакция определяется в обработчике событий, связанных с кнопкой ОК:

Когда пользователь закрывает окно диалога, щелкая на кнопке Close, оно исчезает с экрана. Как и в классе JFrame, программист может изменять эту реакцию с помощью метода setDefaultCloseOperation().

Программа, демонстрирующая использование диалогового окна About, приведена ниже:

Один комментарий на “ Создание диалоговых окон в Java ”

На основе класса Thread, как создать пустое окно, которое произвольно двигаться в пределах монитора?

Создаем собственное всплывающее окно на javascript, css и jQuery. Какой способ выбрать?

Доброго времени суток всем читателям данной статьи. Если для своего веб-сервиса вам необходимо сделать всплывающее окно, то вы нашли правильную публикацию! Сегодня я расскажу вам как создается всплывающее окно JavaScript, css и jQuery инструментами.

В статье подробно будут рассмотрены 3 варианта написания всплывающих окон с затемненным фоном и в конце проведен анализ каждого способа. Любой понравившийся код из представленных примеров вы сможете впоследствии использовать в своих программах. А теперь за дело!

Нет, ну скажите, зачем оно вообще нужно!?

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

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

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

Не могу промолчать и о третьем способе использования всплывающих окон. Это спам и реклама.

Начнем с простого

Теперь мы подошли к самим примерам. Начну я с программной реализации, выполненной при помощи css и html. Я написал приложение, в котором окно всплывает при нажатии на определенную кнопку. В ней я расположил изображение. Однако вы можете впихнуть туда любую информацию, будь то ссылки, текст, фотографии, видео, формы регистрации и так далее.

Цукерберг рекомендует:  Калькулятор индекса массы тела на Swift

Итак, сама разметка веб-страницы вмещается в несколько строк, потому что весь сок состоит в правильной стилизации.

Модальные окна, которые понравятся каждому

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

Это – крайние точки на линейке, которой измеряется наши взаимоотношения с пользователем сайта. В зависимости от привычек, личных предпочтений и способа сёрфинга по сети модальные окна могут быть для пользователя благословением или проклятием.

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

Если появление модального окна произошло автоматически или просто не было в явном виде инициировано пользователем, оно может дезориентировать и раздражать. Это позволяет обвинять модальные окна в назойливости и вторжении в частное пространство пользователя.

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

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

И такие случаи происходят чаще, чем можно ожидать при современном развитии юзабилити-практик и средств тестирования.

Семантика кода способствует доступности сайта

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

Чтобы добиться этого, мы должны внимательно отнестись к семантике разметки. Это требование кажется простым, но, к сожалению, оно часто не выполняется. Представьте себе следующий код окна с кнопкой « Закрыть »:

Чтобы можно было переместить фокус ввода на данный

Допустим, что многие пользователи устройств чтения экрана уже знают о том, что буква « X » означает « Закрыть ». Но если мы заменим эту букву на знак умножения (амперсанд-код ×) или крест (❌) ради визуального эффекта, содержимое нашего блока не будет прочитано.

Лучшим решением в данной ситуации будет использовать тэг для обозначения активного элемента, а также добавить в разметку свойство aria-label , специально предназначенное для устройств чтения экрана:

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

Делаем модальные окна удобными и доступными

Семантическая разметка поможет нам сделать наше модальное окно более удобным и доступным. А правильное использование стилей и скриптов поднимет юзабилити нашего сайта на новый уровень!

Добавление состояния :focus

Используйте состояние :focus в ваших стилях. Это улучшит не только модальные окна, но и всё управление сайтом. Часто состояние :focus , используемое браузером по умолчанию, переписывается css-reset -стилями, или само по себе недостаточно выделяет активные элементы, или не вписывается в общее оформление сайта.

Допустим вариант, когда вы объединяете состояния :focus и :hover :

Хотя, получение фокуса с клавиатуры и наведение указателя мыши – это всё же два различных состояния, и разумно будет дать им собственные, отличные от других стили:

Каждый элемент, способный получить фокус, должен быть стилизован таким образом. В крайнем случае, если вы не хотите использовать свой стиль :focus , позаботьтесь о том, чтобы сохранить дефолтный стиль браузера – обычно это пунктирное подчёркивание или рамка вокруг активного элемента, имеющего фокус.


Сохранение последнего активного элемента

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

Это работает как подобие закладки. Без такой функции пользователь переместится к началу страницы, и будет вынужден искать нужный ему контент заново, что обескураживает. Проблему сохранения фокуса может решить вот такой скрипт:

Перемещение фокуса

При появлении модального окна фокус должен переместиться на него или на первый интерактивный элемент в нём. Тогда пользователю не придётся браться за мышь или перебирать клавишей “ Tab ” десятки полей и кнопок:

На полный экран

Если ваше модальное окно занимает весь экран, позаботьтесь о том, чтобы элементы управления в основном окне стали на время недоступны. Иначе любой пользователь может продолжить вводить что-то в основное окно, думая при этом, что взаимодействует с модальным. Обеспечить желаемое может скрипт, подобный этому:

Закрывая для пользователя основной экран, мы всё же должны обеспечить для него доступ к элементам управления браузером при помощи всё той же кнопки “ Tab ”. Такого поведения от нашего окна ожидают и обычные, зрячие пользователи.

Вышеприведённый скрипт предотвращает переход фокуса в основной документ, вместо этого перемещая его обратно к первому элементу модального окна.

Если мы заодно поместим модальное окно в вершину дерева DOM , сделав его первым потомком , то комбинация “ Shift”+“Tab ” позволит пользователю переключить фокус на элементы управления браузером:

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

Для этого необходимо сохранять в скрипте их идентификаторы. Когда пользователь нажмёт “Tab” в последнем элементе окна, вы переместите фокус на первый элемент. Нажатие “ Shift”+“Tab ” должно обрабатываться зеркально.

Есть и другие варианты обработки перемещения фокуса. Например, вы можете переназначать и использовать в скрипте списки элементов ввода, между которыми разрешён переход фокуса. Или устанавливать tabindex=-1 на скрываемые активные элементы.

Первый и второй методы делают меню и кнопки браузера недоступными при управлении с клавиатуры. При этом походе критичны хорошо заметный элемент закрытия окна и перехват нажатия клавиши “ Esc ” с той же целью. Иначе ваш сайт станет ловушкой для пользователей без мыши.

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

Понятно, что при выборе конкретного метода вы должны учесть все рассмотренные нами факторы.

Закрытие

Модальное окно должно легко закрываться. Стандартные диалоги, вызываемые из JavaScript функцией alert() , могут быть закрыты нажатием клавиши “ Esc ”. Будет хорошим тоном придерживаться этого соглашения при создании собственных диалогов.

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

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

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

Дополнительные меры по обеспечению доступности сайта

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

ARIA-HIDDEN

Устанавливая атрибуту aria-hidden значение true , вы можете скрывать содержимое элемента со всеми его дочерними элементами от программ, читающих экран. Необходимо учесть, что ARIA -элементы не обладают дефолтной стилизацией в браузерах. Чтобы скрыть их от зрячих пользователей, воспользуйтесь следующим CSS -кодом:

Обратите внимание на весьма специфичный селектор. В общем случае мы не хотим прятать абсолютно все элементы с aria-h >X », чтобы понять, что имеется в виду.

ROLE=»DIALOG»

Добавьте свойство role=»dialog» ко всем элементам, содержащим модальный контент. Это укажет так называемым техническим средствам реабилитации, что данный контент требует реакции пользователя. Описанные нами скрипты, зацикливающие перемещение фокуса ввода между допустимыми активными элементами, отлично дополнят эту разметку.

Для оповещений, требующих от пользователя простого подтверждения, используйте role=»alertdialog» совместно с теми же скриптами.

ARIA-LABEL

Свойства aria-label и aria-labelledby используются совместно с role=»dialog» . Если ваше модальное окно имеет заголовок, укажите его идентификатор, например: aria-labelledby=modal_header_id . В противном случае задайте описание диалога в качестве значения свойства aria-label .

Как насчёт HTML5-диалогов?

На момент написания статьи Google Chrome версии 37 и ночные сборки Firefox уже научились поддерживать семантический элемент dialog .

Когда данный элемент станет общеупотребительным, это избавит нас от необходимости проставлять role=dialog в различных элементах. Пока же мы рекомендуем использовать role даже при наличии polyfill -библиотек для обеспечения поддержки устройств чтения экрана.

Замечательно то, что элемент dialog обладает не только семантическим значением, но и теми свойствами, которые могут заменить применяемые нами сегодня скрипты и стили.

Например, чтобы показать или спрятать диалог, мы обычно используем такой скрипт:

Метод show() показывает диалог, вместе с тем оставляя пользователю доступ к остальному сайту. Метод showModal() запускает диалог и запрещает пользователю взаимодействовать с другими элементами сайта.

Элемент dialog имеет свойство open , содержащее true либо false и заменяющее aria-hidden . Псевдо-элемент :backdrop позволит нам использовать особый стиль окна, когда оно запущено при помощи showModal() .

Элемент dialog имеет и другие полезные свойства. Хоть он и не готов пока для использования в массовой разработке, в недалёком будущем он может здорово упростить создание современных, доступных сайтов.

Что дальше?

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

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

Я подготовил демонстрацию модального окна, использующую все вышеперечисленные методы улучшения доступности.

Данная публикация представляет собой перевод статьи « Making Modal Windows Better For Everyone » , подготовленной дружной командой проекта Интернет-технологии.ру

Прикладное программирование с нуля.

AVR, STM, Android, IoT. Встраиваемые системы.

Шаг №45. Создаем оконное приложение на Java для логгера

Всем привет. Как Вы помните в предыдущей статье мы перешли на язык Java для написания небольших приложений по обработки данных, на компьютере, полученных с устройств на микроконтроллере. Также мы условились, что дальнейший материал требует знание начального уровня java. Если его нет, то не расстраивайтесь, самые основы похожи на Си, но объектно-ориентированную часть придется подучить. Литературу я приводил в предыдущей статье.

import java.awt.*; /*Подключаем библиотеку для создания апплетов и независимых
приложений с графическим интерфейсом.*/
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class logWindow extends Frame < /*Создаем подкласс logWindow класса Frame*/
public logWindow () /*Конструктор класса*/
<
super («Логгер»); /*Вызываем конструктор суперкласса и передаем ему параметр, в данном случае имя программы*/
setSize (200,200); /*Метод суперкласса для установкиразмеров окна, в пикселях*/
//Создаем объекты
Button myButton = new Button («Мониторинг»); /*Создаем кнопку и надпись на ней*/
Label myLabel = new Label («Данные логгера»); / Создаем текстовое поле и надпись в нем*/
add (myLabel, BorderLayout.NORTH); /* С помощью менеджера размещения, располагаем текстовое поле в северной части окна*/
add (myButton, BorderLayout.SOUTH); /*Кнопку в южной части*/
myButton.addActionListener (new ActionListener () < /*Для кнопки выбираем событие слушателя, и создаем новое событие в скобках.*/
public void actionPerformed (ActionEvent e) <
myLabel.setText («Мониторинг»); /*Выполняется действие, т.е. при нажатии на кнопку в поле выводится сообщение «Мониторинг» */
>
>);
>
public static vo > //Точка входа программы
logWindow log = new logWindow (); //Создаем объект класса
log.setVisible (true); //Устанавливаем видимость окна
/*Наше окно запускается и отображается, при нажатии на кнопку меняется надпись в текстовом поле. Что бы закрыть окно необходимо добавить код обработки события, который работает следующим образом: мы вызываем для объекта log метод addWindowListener для того, чтобы назначить слушателя оконных событий. В качестве параметра создаем объект абстрактного класса WindowAdapter, в котором создаем класс и переопределяем метод для обработки события закрытия окна — dispose.*/
log.addWindowListener (new WindowAdapter () <
public vo >// в качестве аргумента передаем событие
e.getWindow ().dispose (); // уничтожает объект Frame
>
>);
>
>

Слева на рисунке внешний вид нашего простого оконного приложения на java. На данный момент нас устроит простое меню с одной кнопкой для дальнейших эксперементов. В следующей статье мы научимся мониторить COM — порт, для приема информации с наших устройств, в данном случае такой же строки, которую мы вывели на терминал в статье №42. На этом все. Всем пока.

Скрыть элемент при клике за его пределами / JQuery

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

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

Наша разметка состоит из ссылки (по которой мы будем нажимать, чтобы отобразить/скрыть блок с данными — ) и блоком данных (который содержит маркированный список с цифорками —

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

Здесь мы объявили, что наш блок со списком данных имеет фиксированную ширину — 300px, рамочку — 1px solid и изначально скрыт — display:none;

Теперь перейдем к написанию нашего скрипта. Но перед этим не забываем подключить свежую библиотеку JQuery, так как скрипт будет написан именно на нем. Как подключить библиотеку можно почитать здесь. Итак, сам скрипт:

Скрипт необходимо подключать в конец страницы или после нашего блока, который необходимо скрывать. Если коротко, то скрипт делает следующее: по клику на документе (в любом месте страницы) плавно скрывает блок с классом list — при клике на блоке с классом list ничего не происходит и при клике на ссылке с классом hide — сворачивает и разворачивает блок с классом list — как раз то, что нам и нужно. Пользуйтесь!

Всплывающее окно на HTML и CSS

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

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

Посмотреть пример модального окна можно с помощью JavaScript, воспользовавшись методом alert().

Всплывающее окно

Первым шагом создания всплывающего окна является создание элемента

Используя псевдо-класс :target мы выбираем и применяем стили к элементу, к которому был осуществлён переход. Таким образом после перехода по ссылки значение свойства display элемента

Теперь надо расположить

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

На этом создание простого всплывающего окна закончено.

Модальное окно

Для создания всплывающего модального окна, берём элемент

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

Для эффекта затемнения страницы при выводе модального окна, надо поместить весь имеющийся код окна в дополнительный

Диалоговые окна JOptionPane

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

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

Все стандартные диалоговые окна Swing имеют собственные UI-представители, отвечающие за интерфейс окна в используемом приложении. Это особенно важно для внешних видов окон, имитирующих известные платформы, пользователи которых не должны ощущать значительной разницы при переходе от «родных» приложений к Java-приложениям.

Класс JOptionPane

Интерфейс экземпляра класса JOptionPane имеет структуру, представленную на следующем рисунке. Иконка в интерфейсе может отсутствовать.


Основные диалоговые методы JOptionPane

Наименование метода Описание
showMessageDialog Диалоговое окно вывода сообщения
showConfirmDialog Диалоговое окно подтверждения, с включением кнопок типа yes/no/cancel
showInputDialog Диалоговое окно с выбором

Конструкторы окна сообщений showMessageDialog

Конструкторы окна подтверждения showConfirmDialog

Конструкторы окна выбора showInputDialog

parent — родительское окно.

message — отображаемый в окне текст сообщения. В большинстве случаев это строка, но может быть использован массив строк String[], компонент Component, иконка Icon, представленная меткой JLabel, объект Object, конвертируемый в строку методом toString().

title — заголовок окна.

messageType — тип диалогового окна :

  • INFORMATION_MESSAGE — стандартное диалоговое окно для вывода информации со значком соответствующего вида;
  • WARNING_MESSAGE — стандартное диалоговое окно для вывода предупреждающей информации со значком соответствующего вида;
  • QUESTION_MESSAGE — стандартное диалоговое окно для вывода информации. Как правило, не используется для информационных сообщений;
  • ERROR_MESSAGE — стандартное диалоговое окно для вывода информации об ошибке со значком соответствующего вида;
  • PLAIN_MESSAGE — стандартное диалоговое окно для вывода информации без значка.

optionType — опция определения кнопок управления :

  • DEFAULT_OPTION
  • YES_NO_OPTION
  • YES_NO_CANCEL_OPTION
  • OK_CANCEL_OPTION

selectionValues — список возможных значений. В диалоговом окне InputDialog список будет представлен в компоненте JComboBox или JList. Если selectionValues = null, то в окне будет определено поле JTextField, в которое пользователь может ввести любое значение.

initialSelectionValue — инициализируемое значение.

icon — отображаемая в диалоговом окне иконка.

Локализация кнопок JOptionPane

Кнопки управления, как правило, имеют заголовки «Yes», «No», «Cancel». Для локализации кнопок диалогового компонента JOptionPane можно использовать UIManager следующим образом :

Цукерберг рекомендует:  Code - Нужна помощь в написании кода.

Пример использования JOptionPane

Пример JOptionPaneTest.java включает использование всех типов диалоговых окон JOptionPane. В интерфейсе окна, представленном на следующем скриншоте, размещаются кнопки, по нажатию на которые формируются соответствующие диалоговые окна JOptionPane.

Листинг примера JOptionPane

В методах addMessageListeners(), addConfirmListeners(), addInputListeners() определяются слушатели, обрабатывающие нажатие соответствующих кнопок.

Окна вывода сообщений MessageDialog

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

1. Интерфейс окна вывода сообщений по нажатию на кнопку btnMessage1. Конструктор получает 2 параметра : родитель и текст сообщения. В заголовок подставляется значение «Message». Текст сообщения имеет HTML разметку.

2. Интерфейс окна вывода сообщений по нажатию на кнопку btnMessage2. Конструктор получает 4 параметра : родитель, текст сообщения в виде массива строк, строку заголовка окна и тип сообщения.

3. Интерфейс окна вывода сообщений по нажатию на кнопку btnMessage2. Конструктор получает 5 параметров : родитель, текст сообщения, строку заголовка окна, тип сообщения и иконку.

Диалоговые окна подтверждений ConfirmDialog

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

1. Интерфейс окна подтверждения по нажатию на кнопку btnConfirm1. Конструктор получает 4 параметра : родитель, текст сообщения, строка заголовка и опция кнопок управления

В зависимости от нажатой кнопки открываются следующее окно подтверждение (одно из окон на следующем скриншот), конструктор которого получает 2 параметра. Текст заголовка имеет значение по умолчанию «Select an Option».

2. Интерфейс окна подтверждения по нажатию на кнопку btnConfirm2. Конструктор получает 5 параметров : родитель, текст сообщения, строка заголовка, опция кнопок управления и тип сообщения.

3. Интерфейс окна подтверждения по нажатию на кнопку btnConfirm3. Конструктор получает 6 параметров : родитель, текст сообщения, строка заголовка, опция кнопок управления, тип сообщения и иконка.

Диалоговые окна выбора данных InputDialog

Листинг процедуры создания слушателей, формирующие диалоговые окна выбора

1. Интерфейс окна ввода данных по нажатию на кнопку btnInput1 представлен на скриншоте слева. Конструктор получает 2 параметра : родитель и текст сообщения с разметкой HTML. После ввода значения и нажатия на одну из клавиш открывается окно, представленное на скриншоте справа.

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

3. Интерфейс окна ввода данных по нажатию на кнопку btnInput3 представлен на следующем скриншоте слева. Конструктор получает все возможные параметры : родитель, текстовое сообщение, строка заголовка, тип диалогового окна, иконка, массив строк и выделенное значение по умолчанию. В диалоговом окне возможные значения представлены в компоненте выпадающего списка. После выбора значения и нажатия на одну из клавиш открывается окно вывода сообщения, представленное на скриншоте справа.

Скачать примеры

Исходные коды примеров, рассмотренных на странице, можно скачать здесь (2.25 Кб).

8 Окна и диалоговые панели

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

В составе библиотеки классов AWT имеется несколько классов, предназначенных для работы с окнами. Это класс Window, который произошел от класса Container, и его дочерние классы — Frame, Dialog и FileDialog (рис. 8.1).

Рис. 8.1. Иерархия классов, предназначенных для создания окон

Окно, созданное на базе класса Frame, больше всего похоже на главное окно обычного приложения Windows. Оно может иметь главное меню, для него можно устанавливать форму курсора. Внутри такого окна можно рисовать. Так как окно класса Frame (так же как и другие окна AWT) произошли от класса Container, вы можете добавлять в них различные компоненты и панели, как мы это делали с окнами аплетов и панелей.

На базе класса Dialog создаются окна диалоговых панелей, очень похожих на обычные диалоговые панели Windows. Такие панели не могут иметь меню и обычно предназначены для запроса какой-либо информации у пользователя.

Класс FileDialog предназначен для создания диалоговых панелей, с помощью которых можно выбирать файлы на локальных дисках компьютера. Так как аплеты не могут работать с файлами, в этой книге мы не будем рассматривать класс FileDialog. Информацию о том, как работать с файлами в приложениях Java, а также сведения об этом классе мы планируем включить в следующий том “Библиотеки системного программиста”, посвященный системе разработки Microsoft Visual J++.

Что же касается класса Window, то непосредственно этот класс редко применяется для создания окон, так как классы Frame, Dialog и FileDialog более удобны и обеспечивают все необходимые возможности.

Окна класса Frame

Ниже мы привели краткое описание класса Frame. Так как этот класс реализует интерфейс java.awt.MenuContainer, окно класса Frame может содержать меню.

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

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

Обратите также внимание на вызов метода resize. Этот вызов необходим для задания размеров окна.

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

При создании окна классов Frame и Dialog для них устанавливается режим размещения BorderLayout. Если вам нужен другой режим размещения, необходимо установить его явным образом.

Кроме того, созданное окно появится на экране только после вызова для него метода show.

Убрать окно с экрана вы можете методом hide. Этот метод прячет окно, но оставляет в памяти все связанные с ним ресурсы, поэтому вы сможете вновь отобразить спрятанное окно, вызвав метод show.

В отличие от метода hide, метод dispose удаляет окно и освобождает все связанные с ним ресурсы. Этот метод применяется для окончательного удаления окна с экрана и из памяти.

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

Когда пользователь пытается уничтожить окно класса Frame или Dialog подобным образом, возникает событие Event.WINDOW_DESTROY. Вы должны предусмотреть обработку этого события, выполняя действия, соответствующие логике работы вашего окна. Обычно окно уничтожается вызовом метода dispose, как это показано ниже:

Меню в окне класса Frame

Как мы уже говорили, окно класса Frame может иметь главное меню (Menu Bar) или, как еще говорят, строку меню. Главное меню создается на базе класса MenuBar, краткое описание которого приведено ниже:

Для формирования главного меню окна вы должны создать объект класса MenuBar с помощью конструктора, а затем добавить в него отдельные меню.

Объект главного меню создается следующим образом:

Отдельные меню создаются на базе класса Menu, например:

Создав меню, вы должны добавить в них строки. Для этого нужно вызвать метод add, передав ему в качестве параметра текст строки меню, например:

Далее сформированные меню добавляются в главное меню:

И, наконец, теперь можно устанавливать главное меню в окне класса, созданного на базе класса Frame:

Классы Menu и MenuItem

Для того чтобы дать вам представление о том, что можно делать с меню, приведем краткое описание класса Menu:

Метод addSeparator используется для добавления в меню разделительной строки. Аналогичный результат достигается и при добавлении в меню стоки “-“:

Заметим, что вы можете просто добавлять в меню строки по их названию, пользуясь методом add(String label), либо добавлять в меню элементы класса MenuItem, вызывая метод add(MenuItem mi).

Класс MenuItem определяет поведение отдельных элементов меню:

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

Создание диалоговых панелей

Диалоговые панели создаются на базе класса Dialog, краткое описание которого приведено ниже:

Для того чтобы создать свою диалоговую панель, вы должны определить новый класс, унаследовав его от класса Dialog, как это показано ниже:

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

Для окон класса Dialog устанавливается режим размещения BorderLayout. Если нужен другой режим размещения, необходимо установить его явным образом методом setLayout.


Для отображения окна диалоговой панели необходимо вызвать метод show. Чтобы спрятать диалоговой окно, применяйте метод hide. Метод dispose удаляет окно диалоговой панели окончательно и освобождает все связанные с ним ресурсы.

Когда пользователь пытается уничтожить окно диалоговой панели при помощи органов управления, расположенных в заголовке такого окна, возникает событие Event.WINDOW_DESTROY. Вы должны обработать его, обеспечив удаление окна диалоговой панели вызовом метода dispose, если, конечно, это соответствует логике работы вашей панели.

Приложение FrameWnd

В приложении FrameWnd мы демонстрируем создание окон, меню и диалоговых панелей на базе классов, описанных в этой главе.

В окне аплета FrameWnd расположены две кнопки с названиями Show Frame Window и Hide Frame Window. Первая из них предназначена для отображения окна Main Frame Window, а вторая — для его временного удаления (скрытия).

В окне Main Frame Window мы создали главное меню, содержащее меню File и Help. При выборе любой строки из этого меню, кроме строки Exit меню File, на экране появляется окно диалоговой панели Dialog from Frame с названием выбранной строки меню (рис. 8.2).

Рис. 8.2. Окно и диалоговая панель, создаваемая аплетом FrameWnd

Помимо меню, в окне Main Frame Window находится кнопка OK, нажатие на которую вызывает удаление окна. Кроме того, в нижней части окна отображается строка “Окно класса Frame”.

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

Обратите также внимание на то, что в самой нижней части окно Main Frame Window и Dialog from Frame находится предупреждающее сообщение “Warning: Applet Window”. Это предупреждение пользователю, что данное окно или диалоговая панель выведена не локальным приложением, запущенным на компьютере пользователя, а аплетом, загруженным из сети. Пользователь должен понимать, что данные, введенные им в окнах, созданных аплетами, передаются по сети и могут оказаться доступной кому угодно. Поэтому он не должен вводить конфиденциальную информацию, например, номера своих кредитных карточек.

Исходные тексты приложения

Исходный текст приложения FrameWnd приведен в листинге 8.1.

Листинг 8.1. Файл FrameWnd\FrameWnd.java

Исходный текст документа HTML, созданного для размещения аплета, приведен в листинге 8.2.

Листинг 8.2. Файл FrameWnd\FrameWnd.html

Описание исходного текста

Рассмотрим по очереди поля и методы классов, определенных в нашем приложении.

Поля класса FrameWnd

В поле fMainFrame класса MainFrameWnd хранится ссылка на окно, которое будет создано, если пользователь нажмет кнопку “Show Frame Window”, расположенную в окне аплета. Класс MainFrameWnd создан нами на базе класса Frame.

Поля с именами btnShowFrame и btnHideFrame предназначены, соответственно, для хранения ссылок на только что указанную кнопку и кнопку “Hide Frame Window”, с помощью которой можно скрыть окно.

Метод getAppletInfo класса FrameWnd

Этот метод возвращает информацию об аплете FrameWnd.

Метод init класса FrameWnd

В процессе инициализации аплета метод init создает объект класса MainFrameWnd — перекрывающееся окно с заголовком «Main Frame Window»:

Для этого вызывается конструктор из класса MainFrameWnd, созданного нами на базе класса Frame.

После этого метод init создает две кнопки и добавляет их в окно аплета:

Первая из этих кнопок предназначена для отображения перекрывающегося окна, а вторая — для временного удаления или скрытия этого окна.

Метод destroy класса FrameWnd

При завершении работы аплета мы удаляем созданное нами окно и освобождаем все связанные с ним ресурсы, вызывая для окна метод dispose:

Метод action класса FrameWnd

Назначение метода action класса FrameWnd — обработка событий, вызванных кнопками кнопку “Show Frame Window” и “Hide Frame Window”, созданных в окне аплета:

Если нажата кнопка “Show Frame Window”, для окна fMainFrame вызывается метод show, что приводит к появлению окна на экране. Если нажата кнопка “Hide Frame Window”, для этого окна вызывается метод hide, после чего окно исчезает с экрана. Исчезнувшее окно не уничтожается и вы можете снова отобразить его на экране, нажав кнопку “Show Frame Window”.

Класс MainFrameWnd

Класс MainFrameWnd предназначен для создания автономного перекрывающегося окна, которое существует вне окна навигатора. Этот класс был нами создан на базе класса Frame:

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

Поля класса MainFrameWnd

В поле btnOK хранится ссылка на кнопку, при нажатии которой окно удаляется.

Поле mbMainMenuBar класса MenuBar предназначено для хранения ссылки на главное меню окна. В него мы будем добавлять меню “File” и “Help”, идентификаторы которых хранятся в полях mnFile и mnHelp, соответственно.

Конструктор класса MainFrameWnd

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

Далее конструктор определяет размеры окна, вызывая для него метод resize:

Затем мы устанавливаем для нашего окна желтый цвет фона и черный цвет изображения:

По умолчанию для окон класса Frame устанавливается режим добавления компонент BorderLayout. Мы изменяем этот режим на FlowLayout, вызывая метод setLayout:

Установив новый режим добавления компонент, мы располагаем в нашем окне кнопку, предварительно создав ее с помощью конструктора класса Button:

Далее метод init приступает к формированию главного меню окна. Это меню создается как объект класса MenuBar:

Затем мы создаем и наполняем меню “File”:

Это меню создается на базе класса Menu. Обратите внимание, что между строками New и File расположен разделитель.

Аналогичным образом мы добавляем в главное меню другое меню — “Help”:

После своего окончательного формирования меню “File” и “Help” добавляются в главное меню окна mbMainMenuBar:

И, наконец, когда главное меню будет сформировано, оно подключается к окну вызовом метода setMenuBar, как это показано ниже:

Метод paint класса MainFrameWnd

Метод paint получает в качестве параметра ссылку на контекст отображения, пригодный для рисования в нашем окне. Пользуясь этим контекстом, мы устанавливаем шрифт текста и рисуем текстовую строку. Затем мы вызываем метод paint из базового класса Frame, на основе которого создан наш класс MainFrameWnd:

Метод handleEvent класса MainFrameWnd

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

При получении кода события Event.WINDOW_DESTROY (удаление окна) мы просто скрываем окно, вызывая метод hide:

Все другие события передаются для обработки методу handleEvent из базового класса.

Метод action класса MainFrameWnd

Этот метод обрабатывает события, связанные с кнопкой и меню.

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

Здесь для вас нет ничего нового.

Рассмотрим более подробно процедуру обработки событий от меню.

Вначале метод action проверяет, вызвано ли событие выбором строки из меню, сравнивая объект события с классом MenuItem:

Если это так, в поле mnItem сохраняется ссылка на элемент меню, вызвавший событие:

Однако мы не используем этот элемент, так как для определения строки, выбранной пользователем, нам достаточно проанализировать второй параметр метода action:

В данном случае второй параметр метода action будет представлять собой ссылку на строку, выбранную из меню, поэтому для определения выбранной строки мы можем выполнить простое сравнение методом equals.

Если пользователь выбрал из меню File строку Exit, мы вызываем метод System.exit, предназначенный для завершения работы виртуальной машины Java. Таким способом вы можете завершить работу аплета, когда он выполняется в среде Microsoft Visual J++ в процессе отладки. Если же аплет запущен автономно в навигаторе, то завершения работы навигатора не произойдет.

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

Заметим, что сразу после создания конструктором диалоговая панель не появляется на экране. Мы отображаем ее, вызывая метод show.

Класс MessageBox

Для отображения названий выбранных строк меню мы создаем диалоговую панель, определив свой класс MessageBox на базе класса Dialog, как это показано ниже:

В классе MessageBox есть два поля, конструктор, методы handleEvent и action.

Поля класса MessageBox

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

Ссылка на текстовое поле хранится в поле lbMsg, на кнопку — в поле btnOK.

Конструктор класса MessageBox

Наш конструктор создает диалоговую панель с заданным сообщением внутри нее. Ссылка на строку сообщения передается конструктору через первый параметр. Остальные параметры используются конструктором базового класса Dialog для создания диалоговой панели:

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

Отменяя установленный по умолчанию режим размещения компонент BorderLayout, конструктор устанавливает режим GridLayout:

Окно диалоговой панели при этом разделяется на две части по горизонтали. В верхнюю часть добавляется текстовое поле для отображения сообщения, в нижнюю — кнопка OK:

Метод handleEvent класса MessageBox

Когда пользователь пытается закрыть окно диалоговой панели, например, сделав двойной щелчок левой клавишей мыши по системному меню или одиночный щелчок по кнопке удаления окна, возникает событие Event.WINDOW_DESTROY. Мы его обрабатываем следующим образом:

Вызывая метод dispose, мы удаляем окно диалоговой панели и освобождаем все связанные с ним ресурсы.

Метод action класса MessageBox

Если пользователь нажимает кнопку OK, расположенную в окне диалоговой панели, метод action вызывает для панели метод dispose, удаляя эту панель с экрана и из памяти:

Понравилась статья? Поделиться с друзьями:
Все языки программирования для начинающих