Интерфейс в яве на пальцах. Основы построения графического пользовательского интерфейса Компоненты и контейнеры

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

И так, какие инструменты нам необходимы:

  • Java Virtual Machine (OpenJDK или Oracle JDK)
  • Intellij IDEA (или другое IDE для Java)

После установки необходимого софта, открываем Intellij IDEA и создаем новый проект: File -> New Project…

Я назвал проект guiBase . Как видно на скрине, папка src не содержит ничего, поэтому создаем в ней наш главный класс, содержащий функцию main .

Public class Main { public static void main(String args) { System.out.println("Hello, Govzalla!"); } }

Содеражние главного класса видите выше. Мы уже сейчас можем создать проект (Build project ) и запустить его (Run ). Внизу в терминале вашего IDE вы увидите сообщение “Hello, Govzalla!“ . Но как вы сами поняли — GUI он не поддерживает.

На данном этапе у нас уже есть работающая программа, но без поддержки GUI. А сейчас в той же папке src создадим GUI Form : New -> GUI Form

Открываем созданную GUI форму, нажимаем на JPanel и задаем его идентификатор в поле field name , я задал panel .

После чего перетаскиваем на форму с правой стороны JTextField , JPasswordField и JButton :

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

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

В данный момент мы имеем форму MainWindow и класс MainWindow расширенный с помощью JFrame . Сейчас нам необходимо определить все добавленные GUI элементы как содержание класса MainWindow
this.getContentPane().add(panel);
После чего содержание файла MainWindow.java будет изменено следующим образом:

Import javax.swing.*; public class MainWindow extends JFrame { private JTextField textField1; private JPasswordField passwordField1; private JButton button1; private JPanel panel; public MainWindow() { this.getContentPane().add(panel); } }

Если попробуете запустить код, вы снова увидите то же самое сообщение “Hello, Govzalla!“. Дело в том, что мы создали класс и форму к нему, но не создали инстанцию этого класса.

Пришло время изменить файл Main.java и добавить туда код создания нашего GUI:

Import java.awt.*; public class Main { public static void main(String args) { // Создаем инстанцию класса MainWindow MainWindow mainWindow = new MainWindow(); // Упаковываем все элементы с нашей формы mainWindow.pack(); // Изменяем размеры окна mainWindow.setSize(new Dimension(200, 200)); // Отображаем созданное окно mainWindow.setVisible(true); } }

Запускаем код

Нажав на кнопку Button вы заметите, что программа никак не реагирует. Дело в том, что мы еще не добавили слушатель (Listener ) для событий (Events ) кнопки Button.

Слушатель событий (Event listener ) JButton должен быть имплентацией адаптера ActionListener , поэтому добавим следующий код в тело класса MainWindow :

Private class MyButtonListener implements ActionListener { @Override public void actionPerformed(ActionEvent actionEvent) { } }

Метод actionPerformed () будет обрабатывать все события кнопки button1, но для начала еще необходимо указать кнопке button1 какой класс будет обрабатывать, поэтому добавим следующий код в конструктор класса MainWIndow:
this.button1.addActionListener(new MyButtonListener());
Чтобы наш обработчик не был бессмысленным добавим следующий код в метод actionPerformed ():

@Override public void actionPerformed(ActionEvent actionEvent) { if (textField1.getText().equals(passwordField1.getText())) { JOptionPane.showMessageDialog(null, "Success"); } else { JOptionPane.showMessageDialog(null, "Failure"); } }

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

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

Java AWT

Первой попыткой Sun создать графический интерфейс для Java была библиотека AWT (Abstract Window Toolkit) - инструментарий для работы с различными оконными средами. Sun сделал прослойку на Java, которая вызывает методы из библиотек, написанных на С. Библиотечные методы AWT создают и используют графические компоненты операционной среды. С одной стороны, это хорошо, так как программа на Java похожа на остальные программы в рамках одной ОС. Но при запуске ее на другой платформе могут возникнуть различия в размерах компонентов и шрифтов, которые будут портить внешний вид программы.

Чтобы обеспечить мультиплатформенность AWT интерфейсы вызовов компонентов были унифицированы, вследствии чего их функциональность получилась немного урезанной. Да и набор компонентов получился довольно небольшой. Так например, в AWT нет таблиц, а в кнопках не поддерживается отображение иконок. Тем не менее пакет java.awt входит в Java с самого первого выпуска и его можно использовать для создания графических интерфейсов.

Таким образом, компоненты AWT не выполняют никакой "работы". Это просто «Java-оболочка» для элементов управления той операционной системы, на которой они работают. Все запросы к этим компонентам перенаправляются к операционной системе, которая и выполняет всю работу.

Использованные ресурсы AWT старается освобождать автоматически. Это немного усложняет архитектуру и влияет на производительность. Написать что-то серьезное с использованием AWT будет несколько затруднительно. Сейчас ее используют разве что для апплетов.

Основные концепции SWING

Вслед за AWT Sun разработала графическую библиотеку компонентов Swing , полностью написанную на Java. Для отрисовки используется 2D, что принесло с собой сразу несколько преимуществ. Набор стандартных компонентов значительно превосходит AWT по разнообразию и функциональности. Swing позволяет легко создавать новые компоненты, наследуясь от существующих, и поддерживает различные стили и скины.

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

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

Swing контейнеры высшего уровня

Для создания графического интерфейса приложения необходимо использовать специальные компоненты библиотеки Swing, называемые контейнерами высшего уровня (top level containers). Они представляют собой окна операционной системы, в которых размещаются компоненты пользовательского интерфейса. К контейнерам высшего уровня относятся окна JFrame и JWindow, диалоговое окно JDialog, а также апплет JApplet (который не является окном, но тоже предназначен для вывода интерфейса в браузере, запускающем этот апплет). Контейнеры высшего уровня Swing представляют собой тяжеловесные компоненты и являются исключением из общего правила. Все остальные компоненты Swing являются легковесными.

Простой Swing пример создания оконного интерфейса JFrame .

Import java.awt.Dimension; import javax.swing.JFrame; import javax.swing.JLabel; public class JFrameTest { public static void createGUI() { JFrame frame = new JFrame("Test frame"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel label = new JLabel("Test label"); frame.getContentPane().add(label); frame.setPreferredSize(new Dimension(200, 100)); frame.pack(); frame.setVisible(true); } public static void main(String args) { JFrame.setDefaultLookAndFeelDecorated(true); javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { createGUI(); } }); } }

Конструктор JFrame() без параметров создает пустое окно. Конструктор JFrame(String title) создает пустое окно с заголовком title. Чтобы создать простейшую программу с пустым окном необходимо использовать следующие методы:

  • setSize(int width, int height) - определение размеров окна;
  • setDefaultCloseOperation(int operation) - определение действия при завершении программы;
  • setVisible(boolean visible) - сделать окно видимым.

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

Метод setDefaultCloseOperation определяет действие, которое необходимо выполнить при "выходе из программы". Для этого следует в качестве параметра operation передать константу EXIT_ON_CLOSE, описанную в классе JFrame.

По умолчанию окно создается невидимым. Чтобы отобразить окно на экране вызывается метод setVisible с параметром true. Если вызвать его с параметром false, окно станет невидимым.

Графический интерфейс java swing примера создания окна JFrame представлен на следующем рисунке.

Для подключения библиотеки Swing в приложении необходимо импортировать библиотеку javax.swing .

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

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

На следующем рисунке наглядно представлена структура корневой панели JRootPane .

Корневая панель JRootPane представляет собой контейнер, унаследованный от базового класса Swing JComponent. В этом контейнере за расположение компонентов отвечает специальный менеджер расположения, реализованный во внутреннем классе RootPaneLayout. Этот менеджер расположения отвечает за то, чтобы все составные части корневой панели размещались так, как им следует: многослойная панель занимает все пространство окна; в ее слое FRAME_CONTENT_LAYER располагаются строка меню и панель содержимого, а над всем этим располагется прозрачная панель.

Все составляющие корневой панели JRootPane можно получить или изменить. Для этого у нее есть набор методов get/set. Программным способом JRootPane можно получить с использованием метода getRootPane().

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

Многослойная панель JLayeredPane

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

JLayeredPane используется для добавления в контейнер свойства глубины (depth). To есть, многослойная панель позволяет организовать в контейнере третье измерение, вдоль которого располагаются слои (layers) компонента. В обычном контейнере расположение компонента определяется прямоугольником, который показывает, какую часть контейнера занимает компонент. При добавлении компонента в многослойную панель необходимо указать не только прямоугольник, занимаемый компонентом, но и слой, в котором он будет располагаться. Слой в многослойной панели определяется целым числом. Чем больше определяющее слой число, тем выше слой находится.

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

Возможности многослойной панели широко используются некоторыми компонентами Swing . Особенно они важны для многодокументных приложений, всплывающих подсказок и меню. Многодокументные Swing приложения задействуют специальный контейнер JDesktopPane («рабочий стол»), унаследованный от JLayeredPane , в котором располагаются внутренние окна Swing. Самые важные функции многодокументного приложения - расположение «активного» окна над другими, сворачивание окон, их перетаскивание - обеспечиваются механизмами многослойной панели. Основное преимущество от использования многослойной панели для всплывающих подсказок и меню - это ускорение их работы. Вместо создания для каждой подсказки или меню нового тяжеловесного окна, располагающегося над компонентом, в котором возник запрос на вывод подсказки или меню, Swing создает быстрый легковесный компонент. Этот компонент размещается в достаточно высоком слое многослойной панели выше в стопке всех остальных компонентов и используется для вывода подсказки или меню.

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

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

Слой Palette предназначен для размещения окон с набором инструментов, которые обычно перекрывают остальные элементы интерфейса. Создавать такие окна позволяет панель JDesktopPane, которая размещает их в этом слое.

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

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

Самый верхний слой. Предназначен для операций перетаскивания (drag and drop), которые должны быть хорошо видны в интерфейсе программы.

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

Import javax.swing.*; import java.awt.*; // класс рисования двух типов фигур с текстом class Figure extends JComponent { private static final long serialVersionUID = 1L; private Color color; private int type; private String text; // параметры: цвет и тип фигуры Figure(Color color, int type, String text) { this.color = color; this.type = type; this.text = text; setOpaque(false); } public void paintComponent(Graphics g) { // прорисовка фигуры g.setColor(color); switch (type) { case 0: g.fillOval(0, 0, 90, 90); break; case 1: g.fillRect(0, 0, 130, 80); break; } g.setColor(Color.yellow); g.drawString(text, 10, 35); } } public class JLayeredPaneTest extends JFrame { private static final long serialVersionUID = 1L; public JLayeredPaneTest() { // создание окна super("Example LayeredTest"); // выход при закрытии окна setDefaultCloseOperation(EXIT_ON_CLOSE); // определение многослойной панели JLayeredPane lp = getLayeredPane(); // создание трех фигур Figure figure1 = new Figure(Color.red , 0, "Figure popup"); Figure figure2 = new Figure(Color.blue, 0, "Figure 1"); Figure figure3 = new Figure(Color.cyan, 1, "Figure 2"); // определение местоположения фигур в окне figure1.setBounds(10, 40, 120, 120); figure2.setBounds(60, 120, 160, 180); figure3.setBounds(90, 55, 250, 180); // добавление фигур в различные слои lp.add(figure1, JLayeredPane.POPUP_LAYER); lp.add(figure2, JLayeredPane.PALETTE_LAYER); lp.add(figure3, JLayeredPane.PALETTE_LAYER); // смена позиции одной из фигур lp.setPosition(figure3, 0); // определение размера и открытие окна setSize(280, 250); setVisible(true); } public static void main(String args) { JFrame.setDefaultLookAndFeelDecorated(true); new JLayeredPaneTest(); } }

В примере создается небольшое окно JFrame и в многослойную панель добавляется несколько компонентов Figure. Чтобы получить многослойную панель в любом контейнере Swing высшего уровня, достаточно вызвать метод getLayeredPane() .

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

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

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

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

Панель содержимого ContentPane

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

Обратиться к панели содержимого можно методом getContentPane() класса JFrame. С помощью метода add(Component component) можно добавить на нее любой элемент управления. Заменить ContentPane любой другой панелью типа JPanel можно методом setContentPane()

Пример добавления кнопки в панель содержимого:

JButton newButton = new JButton(); getContentPane().add(newButton);

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

Панель содержимого можно полностью заменить. Рассмотрим следующий Swing пример использования панели содержимого ContentPane .

Import javax.swing.*; public class ContentPaneReplace extends JFrame { private static final long serialVersionUID = 1L; public ContentPaneReplace() { super("Test ContentPane"); setDefaultCloseOperation(EXIT_ON_CLOSE); // Создание панели с двумя кнопками JPanel contents = new JPanel(); contents.add(new JButton("Семья")); contents.add(new JButton("Школа")); // Замена панели содержимого setContentPane(contents); // Определение размера окна setSize(200, 100); // Открытие окна setVisible(true); } public static void main(String args) { JFrame.setDefaultLookAndFeelDecorated(true); new ContentPaneAdd(); } }

В примере создается небольшое окно и панель с двумя кнопками, которая затем методом setContentPane() заменяет панель содержимого окна. Таким образом была использована замена вместо более простого добавления - вызова метода add(). Интерфейс окна представлен на следующем скриншоте.

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

Прозрачная панель JOptionPane

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

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

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

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

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

// Использование прозрачной панели JOptionPane import java.awt.Dimension; import java.awt.Font; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.UIManager; public class JOptionPaneTest extends JFrame { private static final long serialVersionUID = 1L; public static final Font FONT = new Font("Verdana", Font.PLAIN, 11); public static void createGUI() { JFrame frame = new JFrame("Test JOptionPane"); frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); frame.addWindowListener(new WindowListener() { public void windowActivated(WindowEvent event) {} public void windowClosed(WindowEvent event) {} public void windowDeactivated(WindowEvent event) {} public void windowDeiconified(WindowEvent event) {} public void windowIconified(WindowEvent event) {} public void windowOpened(WindowEvent event) {} public void windowClosing(WindowEvent event) { Object options = { "Да", "Нет!" }; int rc = JOptionPane.showOptionDialog(event.getWindow(), "Закрыть окно?", "Подтверждение", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options); if (rc == 0) { event.getWindow().setVisible(false); System.exit(0); } } }); JLabel label = new JLabel("Использование прозрачной панели при закрытии окна"); frame.getContentPane().add(label); frame.setPreferredSize(new Dimension(350, 80)); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { UIManager.put("Button.font", FONT); UIManager.put("Label.font", FONT); JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true); createGUI(); } }); } }

Если методу setDefaultCloseOperation передать константу JFrame.EXIT_ON_CLOSE , то при закрытии окна приложение будет прекращать работу. В примере этому методу передается константа JFrame.DO_NOTHING_ON_CLOSE , чтобы при закрытии окна ничего не происходило. Выход из приложения в примере осуществляется из JFrame слушателя WindowListener в методе windowClosing . При закрытии окна вызывается метод windowClosing с параметром WindowEvent event, который в прозрачной панели Swing JOptionPane открывает диалоговое окно подтверждения.

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

Строка меню JMenuBar

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

Строка меню JMenuBar размещается в многослойной панели в специальном слое FRAME_CONTENT_LAYER и занимает небольшое пространство в верхней части окна. По размерам в длину строка меню равна размеру окна. Ширина строки меню зависит от содержащихся в ней компонентов.

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

Примеры Swing

Исходные коды примеров, рассмотренных в тексте страницы, можно скачать .

Экранной формой называется область, которая видна на экране в виде окна с различными элементами - кнопками, текстом, выпадающими списками и т.п. А сами эти элементы называются компонентами.

Среды, позволяющие в процессе разработки приложения в интерактивном режиме размещать на формы компоненты и задавать их параметры, называются RAD-средами. RAD расшифровывается как Rapid Application Development - быстрая разработка приложений.

В NetBeans и других современных средах разработки такой процесс основан на объектной модели компонентов, поэтому он называется Объектно-Ориентированным Дизайном (OOD – Object-Oriented Design).

NetBeans является RAD-средой и позволяет быстро и удобно создавать приложения с развитым графическим пользовательским интерфейсом (GUI). Хотя языковые конструкции Java, позволяющие это делать, не очень просты, на начальном этапе работы с экранными формами и их элементами нет необходимости вникать в эти тонкости. Достаточно знать основные принципы работы с такими проектами.

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

Во-вторых, такой интерфейс при решении какой-либо задачи позволяет лучше сформулировать, какие параметры надо вводить, какие действия и в какой последовательности выполнять, и что в конце концов получается. И отобразить всё это на экране: вводимым параметрам будут соответствовать пункты ввода текста, действиям – кнопки и пункты меню, результатам – пункты вывода текста.

Пример открытия проекта с существующим исходным кодом.

В NetBeans 5.0 имелся хороший пример GUI-приложения, однако в NetBeans 5.5 он отсутствует. Поэтому для дальнейшей работы следует скопировать аналогичный пример с сайта автора или сайта, на котором выложен данный учебный курс. Пример называется JavaApplicationGUI_example.

Сначала следует распаковать zip-архив, и извлечь находящуюся в нём папку с файлами проекта в папку с вашими проектами (например, C:\Documents and Settings\User). Затем запустить среду NetBeans, если она не была запущена, и закрыть имеющиеся открытые проекты, чтобы они не мешали. После чего выбрать в меню File/Open Project, либо или на панели инструментов иконку с открывающейся фиолетовой папочкой, либо нажать комбинацию клавиш ++O. В открывшемся диалоге выбрать папку JavaApplicationGUI_example (лучше в неё не заходить, а просто установить выделение на эту папку), после чего нажать кнопку Open Project Folder.

При этом, если не снимать галочку “Open as Main Project”, проект автоматически становится главным.

В окне редактора исходного кода появится следующий текст:

* GUI_application.java

package java_gui_example;

* @author Вадим Монахов

public class GUI_application extends javax.swing.JFrame {

* Creates new form GUI_application

public GUI_application() {

initComponents();

/** This method is called from within the constructor to

* initialize the form.

* WARNING: Do NOT modify this code. The content of this method is

* always regenerated by the Form Editor.

private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt)

* @param args the command line arguments

public static void main(String args) {

java.awt.EventQueue.invokeLater(new Runnable() {

public void run() {

new GUI_application().setVisible(true);

// Variables declaration - do not modify

private javax.swing.JMenuItem aboutMenuItem;

private javax.swing.JMenuItem contentsMenuItem;

private javax.swing.JMenuItem copyMenuItem;

private javax.swing.JMenuItem cutMenuItem;

private javax.swing.JMenuItem deleteMenuItem;

private javax.swing.JMenu editMenu;

private javax.swing.JMenuItem exitMenuItem;

private javax.swing.JMenu fileMenu;

private javax.swing.JMenu helpMenu;

private javax.swing.JMenuBar menuBar;

private javax.swing.JMenuItem openMenuItem;

private javax.swing.JMenuItem pasteMenuItem;

private javax.swing.JMenuItem saveAsMenuItem;

private javax.swing.JMenuItem saveMenuItem;

// End of variables declaration

Поясним некоторые его части. Указание пакета java_gui_example, в котором будет располагаться код класса приложения, нам уже знакомо. Декларация самого класса GUI_application в данном случае несколько сложнее, чем раньше:

public class GUI_application extends javax.swing.JFrame

Она означает, что задаётся общедоступный класс GUI_application, который является наследником класса JFrame, заданного в пакете swing, вложенном в пакет javax. Слово extends переводится как “расширяет” (класс-наследник всегда расширяет возможности класса-прародителя).

Общедоступный конструктор GUI_application()создаёт объект приложения и инициализирует все его компоненты, методом initComponents(), автоматически генерируемом средой разработки и скрываемом в исходном коде узлом +Generated Code.

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

private void exitMenuItemActionPerformed

Он будет обсуждаться чуть позже. Метод

public static void main(String args)

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

Запущенное приложение. Приложение с раскрытым меню.

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

Именно за нажатие на этот пункт меню несёт ответственность оператор exitMenuItemActionPerformed. При проектировании экранной формы он назначен в качестве обработчика события – подпрограммы, которая выполняется при наступлении события. В нашем случае событием является выбор пункта меню Exit, и при этом вызывается обработчик exitMenuItemActionPerformed. Внутри него имеется всего одна строчка

Она вызывает прекращение выполнения метода main и выход из приложения с нулевым кодом завершения. Как правило, ненулевой код завершения возвращают при аварийном завершении приложения для того, чтобы по его значению можно было выяснить причины “вылета” программы.

Редактор экранных форм

Нажмём закладку Design (“дизайн”) в левой верхней части редактора исходного кода. При этом мы переключимся из режима редактирования исходного кода (активна закладка Source – “исходный код”) в режим редактирования экранной формы, как это показано на рисунке.

Редактирование экранной формы.

Вместо исходного кода показывается внешний вид экранной формы и находящиеся на ней компоненты. Справа от окна, в котором показывается экранная форма в режиме редактирования, расположены окна Palette (“палитра”) палитры компонентов и окно Properties (“свойства”) показа и редактирования свойств текущего компонента.

Свойство – это поле данных, которое после изменения значения может проделать какое-либо действие. Например, при изменении значения ширины компонента отрисовать на экране компонент с новой шириной. “Обычное” поле данных на такое не способно. Таким образом, свойство – это “умное поле данных”.

Палитра компонентов предназначена для выбора типа компонента, который нужен программисту для размещения на экранной форме. Например, добавим на нашу форму компонент типа JButton (сокращение от Java Button – “кнопка Java”). Для этого щёлкнем мышью по пункту JButton на палитре и передвинем мышь в нужное место экранной формы. При попадании мыши в область экранной формы на ней появляется кнопка стандартного размера, которая передвигается вместе с мышью. Щелчок в нужном месте формы приводит к тому, что кнопка остаётся в этом месте. Вокруг неё показываются рамка и маленькие квадратики, обозначающие, что наш компонент является выделенным. Для него осуществляется показ и редактирование свойств в окне Properties.

Кроме того, от выделенного компонента исходят линии, к которым идет привязка для задания положения компонента на форме.

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

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

Введём на кнопке надпись “OK” – используем эту кнопку для выхода из программы.

Редактирование свойств компонента

Размер компонента задаётся мышью путём хватания за рамку и расширения или сужения по соответствующим направлениям. Установка на новое место – перетаскиванием компонента мышью.

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

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

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

Булевские свойства в колонке значений свойств показываются в виде кнопок выбора checkbox – квадратиков с возможностью установки галочки внутри. Если галочки нет, значение свойства false, если есть – true.

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

Название свойства Что оно задаёт
background Цвет фона
componentPopupMenu Позволяет назначать всплывающее меню, появляющееся по нажатию правой кнопкой мыши в области компонента.
font Фонт, которым делается надпись на компоненте.
foreground Цвет фонта, которым делается надпись на компоненте.
icon Картинка, которая рисуется на компоненте рядом с текстом.
text Текст (надпись) на компоненте.
toolTipText Всплывающая подсказка, появляющаяся через некоторое время при наведении курсора мыши на компонент.
border Тип рамки вокруг компонента.
borderPainted Рисуется ли рамка вокруг компонента.
contentAreaFilled Имеется ли заполнение цветом внутренней области компонента (для кнопок оно создаёт эффект трёхмерности, без заполнения кнопка выглядит плоской).
defaultCapable Способна ли кнопка быть “кнопкой по умолчанию”: при нажатии автоматически происходит нажатие “кнопки по умолчанию” (такая кнопка на экранной форме должна быть одна).
enabled Доступен ли компонент. По умолчанию все создаваемые на форме компоненты доступны. Недоступные компоненты рисуются более блеклыми красками.

В качестве примера добавим всплывающую подсказку для нашей кнопки: введём текст “Эта кнопка предназначена для выхода из программы” в поле, соответствующее свойству toolTipText. К сожалению, подсказка может быть только однострочной – символы перевода на новую строку при выводе подсказки игнорируются, даже если они заданы в строке программным путём.

Наконец, зададим действие, которое будет выполняться при нажатии на кнопку – обработчик события (event handler) нажатия на кнопку. Для этого сначала выделим кнопку, после чего щёлкнем по ней правой кнопкой мыши, и в появившемся всплывающем меню выберем пункт Events/Action/actionPerformed.

Назначение обработчика события

Events означает “События”, Action – “Действие”, actionPerformed – “выполненное действие”.

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

// TODO add your handling code here:

Аналогичный результат можно получить и более быстрым способом – после того, как мы выделим кнопку в окне редактирования формы (Design), в окне Navigator показывается и выделяется имя этой кнопки. Двойной щелчок по этому имени в окне навигатора приводит к созданию заготовки обработчика события.

Рядом с обработчиком jButton1ActionPerformed будет расположен уже имеющийся обработчик события, срабатывающий при нажатии на пункт меню “Выход”:

private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {

Заменим в нашем обработчике события строку с комментарием на код, вызывающий выход из программы:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {

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

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

javax.swing.JOptionPane.showMessageDialog(null,"Меня нажали");

Если классы пакета javax.swing импортированы, префикс javax.swing при вызове не нужен.

Внешний вид приложения

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

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

Кроме того, наше приложение появляется в левом верхнем углу экрана, а хотелось бы, чтобы оно появлялось в центре.

Для того, чтобы показать приложение в платформо-ориентированном виде (то есть в том виде, который использует компоненты и настройки операционной системы), требуется изменить код конструктора приложения, вставив перед вызовом метода initComponents задание типа пользовательского интерфейса (User’s Interface, сокращённо UI):

import javax.swing.*;

import java.awt.*;

public GUI_application() {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

}catch(Exception e){};

initComponents();

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

Dimension frameSize = getSize();

setLocation(new Point((screenSize.width-frameSize.width)/2,

(screenSize.height-frameSize.width)/2)

Внешний вид запущенного приложения с платформо-ориентированным пользовательским интерфейсом в операционной системе Windows ® XP

Код, следующий после вызова initComponents(), предназначен для установки окна приложения в центр экрана.

Имеется возможность задания ещё одного платформо-независимого вида приложения – в стиле Motiff, используемого в операционной системе Solaris ® . Для установки такого вида вместо вызова

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()

Следует написать

UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");

Внешний вид запущенного приложения с платформо-независимым пользовательским интерфейсом в стиле Motiff

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

Ведение проектов

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

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

· При создании нового проекта среда разработки предлагает ввести имя папки, где его хранить - следует указать имя папки архива. Кроме того, предлагается ввести имя проекта. Это имя будет использовано средой NetBeans для создания папки проекта, так и для названия вашего приложения. Для того, чтобы облегчить работу с вашим приложением в разных странах, рекомендуется делать это название англоязычным. В папке проекта среда разработки автоматически создаст систему вложенных папок проекта и все его файлы. Структура папок проектов NetBeans была описана ранее.

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

· При получении сколько-нибудь работоспособной версии проекта следует делать его архивную копию. Для этого в открытом проекте в окне “Projects” достаточно щелкнуть правой кнопкой мыши по имени проекта, и в появившемся всплывающем меню выбрать пункт “Copy Project”. Откроется диалоговая форма, в которой предлагается автоматически образованное имя копии – к первоначальному имени проекта добавляется подчёркивание и номер копии. Для первой копии это _1, для второй _2, и так далее. Причём головная папка архива по умолчанию остаётся той же, что и у первоначального проекта. Что очень удобно, поскольку даёт возможность создавать копию всего тремя щелчками мышки без набора чего-либо с клавиатуры.

Создание рабочей копии проекта

Скопированный проект автоматически возникает в окне “Projects”, но не становится главным. То есть вы продолжаете работать с прежним проектом, и все его открытые окна сохраняются. Можно сразу закрыть новый проект – правой кнопкой мыши щёлкнуть по его имени, и в появившемся всплывающем меню выбрать пункт “Close Project”.

Для чего нужна такая система ведения проектов? Дело в том, что у начинающих программистов имеется обыкновение разрушать результаты собственного труда. Они развивают проект, не сохраняя архивов. Доводят его до почти работающего состояния, после чего ещё немного усовершенствуют, затем ещё – и всё перестаёт работать. А так как они вконец запутываются, восстановить работающую версию уже нет возможности. И им нечего предъявить преподавателю или начальнику!

Поэтому следует приучиться копировать в архив все промежуточные версии проекта, более работоспособные, чем уже сохранённые в архив. В реальных проектах трудно запомнить все изменения, сделанные в конкретной версии, и, что важнее, все взаимосвязи, вызвавшие эти изменения. Поэтому даже опытным программистам время от времени приходится констатировать: “Ничего не получается!” И восстанавливать версию, в которой ещё не было тех нововведений, которые привели к путанице. Кроме того, часто бывает, что новая версия в каких-то ситуациях работает неправильно. И приходится возвращаться на десятки версий назад в поисках той, где не было таких “глюков”. А затем внимательно сравнивать работу двух версий, выясняя причину неправильной работы более поздней версии. Или убеждаться, что все предыдущие версии также работали неправильно, просто ошибку не замечали.

  • Внешняя политика СССР в годы войны. Ленд-лиз. Тегеранская конференция. Ялтинская и Потсдамская конференции 1945 г. Создание ООН.
  • Внешняя политика СССР в годы войны.Ленд-лиз. Тегеранская конференция. Ялтинская и Потсдамская конференция 1945г.Создание ООН.
  • Возобновелние деятельности БСГ. Создание белнац партий и организаций

  • Предоставлено Салимом Гулом (Saleem Gul) и Томасом Павеком (Tomas Pavek)

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

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

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

    Предполагаемая продолжительность: 20 минут

    Упражнение 1: Создание проекта

    Первым действием является создание проекта среды IDE для разрабатываемого приложения. Дадим проекту имя NumberAddition .

    1. Выберите "Файл" > "Создать проект" . Также можно щелкнуть значок "New Project" на панели инструментов среды IDE.
    2. В области "Categories" выберите узел "Java". В области "Projects" выберите "Java Application". Нажмите кнопку "Далее".
    3. Введите NumberAddition в поле Project Name ("Имя проекта") и укажите путь, например, в вашем основном каталоге, как местоположение проекта.
    4. Установите флажок "Использовать отдельную папку для хранения библиотек" и укажите местоположение папки библиотек (необязательно). Дополнительная информация приведена в статье Предоставление доступа к библиотеке другим пользователям в документе Разработка приложений с помощью NetBeans IDE .
    5. Удалите флажок "Create Main Class", если он установлен.
    6. Нажмите кнопку "Готово".

    Упражнение 2: Создание внешнего интерфейса

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

    Создание контейнера JFrame

    1. В окне "Проекты" щелкните правой кнопкой мыши узел NumberAddition и выберите Создать > Другие.
    2. В диалоговом окне создания файла выберите категорию Swing GUI Forms и тип файла JFrame Form . Нажмите кнопку "Далее".
    3. Введите NumberAdditionUI в качестве имени класса.
    4. Выберите пакет my.numberaddition .
    5. Нажмите кнопку "Готово".

    Среда IDE создает форму NumberAdditionUI и класс NumberAdditionUI в приложении NumberAddition и открывает форму NumberAdditionUI в GUI Builder. Пакет my.NumberAddition заменяет собой пакет по умолчанию.

    Добавление элементов: создание внешнего интерфейса

    Далее с помощью окна "Palette" внешний интерфейс приложения заполняется панелью JPanel. После этого добавляются три элемента JLabel (текстовые подписи), три элемента JTextField (текстовые поля) и три элемента JButton (кнопки). Если до этого работа с конструктором графического интерфейса пользователя не выполнялась сведения о размещения компонентов см. в разделе Разработка графического пользовательского интерфейса Swing в IDE NetBeans .

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

    Если в правом верхнем углу среды IDE отсутствует окно Palette ("Палитра"), выберите Window ("Окно") > Palette ("Палитра").

    1. Для начала выберите панель из категории Swing Containers ("Контейнеры Swing") в палитре и перетащите ее на JFrame.
    2. Панель JPanel будет выделена. Перейдите к окну "Properties" и нажмите кнопку с многоточием (...) рядом с полем "Border" для выбора стиля границы.
    3. В диалоговом окне "Border" выберите "TitledBorder" из списка и введите Number Addition в поле "Title". Для сохранения изменений и закрытия диалогового окна нажмите кнопку "OK".
    4. Теперь на экране должен отображаться пустой элемент "JFrame" с заголовком "Number Addition", как показано на рисунке. Согласно рисунку добавьте к нему три метки JLabel, три текстовых поля JTextField и три кнопки JButton.

    Переименование элементов

    На этом этапе будет выполнено переименование элементов, которые были добавлены к элементу JFrame.

    1. Дважды щелкните jLabel1 и измените ntrcn (свойство "text") на First Number .
    2. Дважды щелкните jLabel2 и измените текст на Second Number .
    3. Дважды щелкните jLabel3 и измените текст на Result .
    4. Удалите стандартный текст из jTextField1 . Отображаемый текст можно преобразовать в редактируемый. Для этого щелкните правой кнопкой мыши текстовое поле и выберите "Редактировать текст" во всплывающем меню. При этом может потребоваться восстановить первоначальный размер поля jTextField1 . Повторите это действие для полей jTextField2 и jTextField3 .
    5. Измените отображаемый текст jButton1 на Clear . (Для изменения текста кнопки щелкните кнопку правой кнопкой мыши и выберите "Edit Text". В качестве альтернативы можно щелкнуть кнопку, выдержать паузу и щелкнуть еще раз.)
    6. Измените отображаемый текст jButton2 на Add .
    7. Измените отображаемый текст jButton3 на Exit .

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

    Упражнение 3: Добавление функциональности

    В этом упражнении будет добавлена необходимая функциональность к кнопкам "Add", "Clear" и "Exit". Поля jTextField1 и jTextField2 будут использоваться для ввода значений пользователем, а jTextField3 - для вывода результата работы программы. Создаваемая программа представляет собой простейший калькулятор. Итак, приступим!

    Добавление функциональности к кнопке "Exit"

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

    1. Щелкните правой кнопкой мыши кнопку "Exit". Во всплывающем меню выберите Events ("События") > Action ("Действие") > actionPerformed. Учтите, что меню содержит множество других событий, на которые может реагировать программа! При выборе события actionPerformed среда IDE автоматически добавит прослушиватель ActionListener к кнопке Exit ("Выход") и создаст метод обработчика для обработки метода прослушивателя actionPerformed.
    2. В среде IDE автоматически открывается окно "Source Code", где отображается место вставки действия, которое должно выполняться кнопкой при ее нажатии (с помощью мыши или клавиатуры). Окно "Source Code" должно содержать следующие строки: private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) { //TODO add your handling code here: }
    3. Теперь добавим код действия, которое должна выполнять кнопка "Exit". Замените строку TODO на System.exit(0); . Готовый код кнопки "Exit" должен выглядеть следующим образом: private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) { System.exit(0); }

    Добавление функциональности к кнопке "Clear"

    1. Щелкните правой кнопкой мыши кнопку "Clear" (jButton1). В появившемся меню выберите "Events > Action > actionPerformed".
    2. Нажатие кнопки "Clear" должно приводить к удалению всего текста из всех текстовых полей "jTextField". Для этого следует добавить код, аналогичный приведенному выше. Готовый исходный код должен выглядеть следующим образом: private void jButton1ActionPerformed(java.awt.event.ActionEvent evt){ jTextField1.setText(""); jTextField2.setText(""); jTextField3.setText(""); }

    Этот код удаляет текст из всех трех полей JTextField, оставляя их пустыми.

    Добавление функциональности к кнопке "Add"

    Кнопка "Add" должна выполнять три действия.

    1. Сначала она принимает данные, введенные пользователем в полях jTextField1 и jTextField2 , и преобразовывает их из типа "String" в тип "Float".
    2. Затем она выполнит сложение двух чисел.
    3. И, наконец, она преобразует сумму в тип String и поместит ее в jTextField3 .
    Начнем!
    1. Щелкните вкладку "Design" в верхней части рабочей области для возврата к экрану "Form Design".
    2. Щелкните правой кнопкой мыши кнопку "Add" (jButton2). Во всплывающем меню выберите Events ("События") > Action ("Действие") > actionPerformed.
    3. Добавьте код действий, которые должна выполнять кнопка "Add". Готовый исходный код должен выглядеть следующим образом: private void jButton2ActionPerformed(java.awt.event.ActionEvent evt){ // First we define float variables. float num1, num2, result; // We have to parse the text to a type float. num1 = Float.parseFloat(jTextField1.getText()); num2 = Float.parseFloat(jTextField2.getText()); // Now we can perform the addition. result = num1+num2; // We will now pass the value of result to jTextField3. // At the same time, we are going to // change the value of result from a float to a string. jTextField3.setText(String.valueOf(result)); }

    Теперь программа полностью готова, и можно приступить к ее сборке и выполнению.

    Упражнение 4: Выполнение программы

    Для выполнения программы в среде IDE выполните следующие действия:

    1. Выберите Run ("Запуск") > Run Main Project ("Запуск главного проекта") (как вариант, нажмите F6).

      Примечание. При открытии окна с указанием того, что для Project NumberAddition не задан основной класс, следует выбрать my.NumberAddition.NumberAdditionUI в качестве основного класса в том же окне и нажать кнопку ОК.

    Для запуска программы вне среды IDE выполните следующие действия:

    Через несколько секунд приложение запустится.

    Примечание. Если при двойном щелчке файла JAR не выполняется запуск приложения, дополнительные сведения о настройке связей файлов JAR в используемой операционной системе см .

    Можно также запустить приложение из командной строки.

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

    1. Вызовите командную строку или окно терминала.
    2. В командной строке измените текущий каталог на каталог NumberAddition/dist .
    3. В командной строке введите следующий оператор: java -jar NumberAddition.jar

      Примечание. Убедитесь, что my.NumberAddition.NumberAdditionUI задан как основной класс до запуска приложения. Для провери этого, щелкните правой кнопкой узел мыши узел проекта NumberAddition на панели "Проекты", выберите "Свойства" во всплывающем меню и выберите категорию "Выполнить" в диалоговом окне "Свойства проекта". В поле "Основной класс" должно отображаться my.numberaddition.NumberAdditionUI .

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

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

    1. Вернитесь к файлу NumberAdditionUI.java в редакторе. Щелкните вкладку "Design" для просмотра структуры графического интерфейса в GUI Builder.
    2. Щелкните правой кнопкой мыши любой элемент графического интерфейса и выберите "Events" в появившемся меню. Теперь можно просто изучить содержимое меню, не выбирая каких-либо пунктов.
    3. В качестве альтернативы можно выбрать "Properties" в меню "Window". В окне "Properties" щелкните вкладку "Events". Вкладка "Events" позволяет просмотреть и изменить обработчики событий, связанные с текущим активным элементом графического интерфейса.
    4. Приложение также может реагировать на нажатие клавиш, одинарный, двойной или тройной щелчок мышью, перемещение указателя мыши, изменение размера окна и перемещение фокуса ввода. Меню "Events" позволяет автоматически создать обработчики событий для всех этих событий. Наиболее распространенным из них является событие "Action". (Для получения дополнительных сведений см. практические рекомендации по обработке событий в руководстве Sun Java Events Tutorial .)

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

    1. Вернитесь к файлу NumberAdditionUI.java в редакторе. Щелкните вкладку "Source" для просмотра исходного кода графического интерфейса.
    2. Выполните прокрутку вниз и просмотрите реализованные методы jButton1ActionPerformed() , jButton2ActionPerformed() и jButton3ActionPerformed() . Эти методы называются обработчиками событий.
    3. Теперь перейдите к методу initComponents() . Если этот метод отсутствует, найдите строку Generated Code и щелкните знак + рядом с этой строкой для отображения скрытого метода initComponents() .
    4. Обратите внимание на синий блок, окружающий метод initComponents() . Этот код был автоматически создан средой IDE и не может быть изменен пользователем.
    5. Теперь посмотрите на сам метод initComponents() . Помимо прочего, он содержит код, инициализирующий элементы графического интерфейса и помещающий их в форму. Этот код создается и обновляется автоматически при размещении и изменении элементов в режиме проектирования.
    6. В методе initComponents() найдите следующий фрагмент: jButton3.setText("Exit"); jButton3.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { jButton3ActionPerformed(evt); } });

      В этом месте к элементу графического интерфейса, в данном случае к jButton3 , добавляется объект прослушивания событий "ActionListener". Интерфейс "ActionListener" имеет метод "actionPerformed" объекта "ActionEvent", который реализуется путем простого вызова обработчика событий jButton3ActionPerformed . Теперь эта кнопка реагирует на события действий. Каждый раз при нажатии кнопки создается событие "ActionEvent", которое передается в метод "actionPerformed" интерфейса прослушивания событий, исполняющий код, предусмотренный разработчиком для этого события в обработчике событий.

    7. Учебная карта по приложениям с графическим интерфейсом Java

    В Java есть 2 основных пакета для создания графических интерфейсов (Graphics User Interface). Это Abstract Windows Toolkit (AWT) и Swing. AWT использует виджеты операционной системы, поэтому эта библиотека немного быстрее. Но на мой взгляд, Swing более хорошо спроектирован.

    В данном туториале мы рассмотрим основные элементы библиотеки Swing и создадим простой интерфейс (GUI) в качестве примера.

    Для группировки компонент интерфейса используются контейнеры (Container). Для создания основного контейнера для приложения чаще всего используется контейнер JFrame (есть еще JWindows и JApplet). Проще всего унаследоваться от JFrame тем самым получить доступ ко множеству методов, например:

    setBounds(x, y, w, h) - указывает координаты верхней левой вершины окна, а также его ширину и высоту.

    setResizable(bool) - указывает, можно ли изменять размер окна.

    setTitle(str) - устанавливает название окна.

    setVisible(bool) - собственно отображает окно.

    setDefaultCloseOperation(operation) - указывает операцию, которая будет произведена при закрытии окна.

    Основные элементы управления:

    • JLabel - элемент для отображения фиксированного текста;
    • JTextField - простой edit-box;
    • JButton - обычная кнопка (button);
    • JCheckBox - элемент выбора (аналог checkbox);
    • JRadioButton - радио кнопка

    Как видите, все довольно просто и логично.

    При отображении элементов управления используются специальные менеджеры - LayoutManager. У всех LayoutManager"ов есть методы для добавления у удаления элементов.

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

    GridLayout - отображения элементов в виде таблицы с одинаковыми размерами ячеек.

    BorderLayout - используется при отображении не более 5 элементов. Эти элементы располагаются по краям фрейма и в ценрте: North, South, East, West, Center.

    BoxLayout - отображает элементы в виде рядка или колонки.

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

    Стоит еще обратить внимание на обработку событий. Для этого используются так называемые Event Listeners.

    Ну все, довольно теории, перейдем к примеру GUI:

    Import java.awt.*; import java.awt.event.*; import javax.swing.*; public class SimpleGUI extends JFrame { private JButton button = new JButton("Press"); private JTextField input = new JTextField("", 5); private JLabel label = new JLabel("Input:"); private JRadioButton radio1 = new JRadioButton("Select this"); private JRadioButton radio2 = new JRadioButton("Select that"); private JCheckBox check = new JCheckBox("Check", false); public SimpleGUI() { super("Simple Example"); this.setBounds(100,100,250,100); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container container = this.getContentPane(); container.setLayout(new GridLayout(3,2,2,2)); container.add(label); container.add(input); ButtonGroup group = new ButtonGroup(); group.add(radio1); group.add(radio2); container.add(radio1); radio1.setSelected(true); container.add(radio2); container.add(check); button.addActionListener(new ButtonEventListener()); container.add(button); } class ButtonEventListener implements ActionListener { public void actionPerformed(ActionEvent e) { String message = ""; message += "Button was pressed\n"; message += "Text is " + input.getText() + "\n"; message += (radio1.isSelected()?"Radio #1":"Radio #2") + " is selected\n"; message += "CheckBox is " + ((check.isSelected()) ?"checked":"unchecked"); JOptionPane.showMessageDialog(null, message, "Output", JOptionPane.PLAIN_MESSAGE); } } public static void main(String args) { SimpleGUI app = new SimpleGUI(); app.setVisible(true); } }

    Примечания:

    getContentPane возвращает контейнер верхнего уровня. ButtonGroup служит для создания группы взаимосвязанных радио-кнопок.

    Внутренний класс ButtonActionListener реализует интерфейс ActionListener. Для этого необходимо предоставить имплементацию метода actionPerformed.

    JOptionPane служит для отображения диалоговых окон.

    Жду ваших вопросов и комментариев. Если вы хотите больше узнать о Swing, скажите об этом, и в скором времени я напишу еще одну статью с более сложными приемами и компонентами.