Как сделать приложение с интерфейсом на java

Обновлено: 08.05.2024

Однажды у меня возникла идея, написать небольшое настольное приложение для своих нужд — что-то типа небольшого словаря для изучения иностранных слов — и я начал ломать голову, а как бы мне это сделать? Естественно, первое, что мне пришло в голову — Swing. Все наверняка слышали о Swing . Это библиотека для создания пользовательских, графических интерфейсов. В связи с тем, что наш горячо любимый Oracle еще не полностью отказался от Swing, он не считается устаревшим, и приложения на нем по-прежнему работают. Однако он больше не модернизируется Swing, и ребята из Oracle дали нам понять, что за JavaFX будущее. Да и по сути, JavaFX использует компоненты Swing как поставщика услуг)

Что такое JavaFX?

Особенности JavaFX:

  • JavaFX изначально поставляется с большим набором частей графического интерфейса, таких как всякие там кнопки, текстовые поля, таблицы, деревья, меню, диаграммы и т.д., что в свою очередь сэкономит нам вагон времени.
  • JavaFX часто юзает стили CSS, и мы сможем использовать специальный формат FXML для создания GUI, а не делать это в коде Java. Это облегчает быстрое размещение графического интерфейса пользователя или изменение внешнего вида или композиции без необходимости долго играться в коде Java.
  • JavaFX имеет готовые к использованию части диаграммы, поэтому нам не нужно писать их с нуля в любое время, когда вам нужна базовая диаграмма.
  • JavaFX дополнительно поставляется с поддержкой 3D графики, которая часто полезна, если мы разрабатываем какую-то игру или подобные приложения.
  • Stage — по сути это окружающее окно, которое используется как начальное полотно и содержит в себе остальные компоненты. У приложения может быть несколько stage, но один такой компонент должен быть в любом случае. По сути Stage является основным контейнером и точкой входа.
  • Scene — отображает содержание stage (прям матрёшка). Каждый stage может содержать несколько компонентов — scene, которые можно между собой переключать. Внутри это реализуется графом объектов, который называется — Scene Graph (где каждый элемент — узел, ещё называемый как Node ).
  • Node — это элементы управления, например, кнопки метки, или даже макеты (layout), внутри которых может быть несколько вложенных компонентов. У каждой сцены (scene) может быть один вложенный узел (node), но это может быть макет (layout) с несколькими компонентами. Вложенность может быть многоуровневой, когда макеты содержат другие макеты и обычные компоненты. У каждого такого узла есть свой идентификатор, стиль, эффекты, состояние, обработчики событий.

JavaFX: примеры использования

Знакомство с JavaFX SceneBuilder

Введение в Java FX - 8

Именно на этом моменте на сцену выходит (барабанная дробь) — SceneBuilder В JavaFX Scene Builder — это инструмент, с помощью которого мы можем конструировать наши окна в виде графического интерфейса и после их сохранять, и эта программа на основании результата будет конструировать xml файлы, которые мы будем подтягивать в нашем приложении. Как-то так выглядит интерфейс данного fmxl-строителя:

Небольшое отступление. JavaFX уроки

  • delete — по индексу удаляем выбранную(выделенную) собаку;
  • edit — создаем новую собаку с переданными данными, и задаем ее вместо той которая была до этого;
  • create — создаем новую собаку и дергаем метод вызова окна создания, передав новый объект, и после закрытия которого если имя не null, то сохраняем нового питомца.

Введение в Java FX - 14

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

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

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

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

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

netbeans stamp 80 74 73

Figure 1. Содержимое этой страницы применимо к IDE NetBeans 6.9 и более поздним версиям

Для работы с этим учебным курсом требуются программное обеспечение и ресурсы, перечисленные ниже.

версия 6.9 или более поздняя

версия 6, 7 или 8

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

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

Выберите "Файл" > "Создать проект" . Также можно щелкнуть значок "New Project" на панели инструментов среды IDE.

Введите NumberAddition в поле Project Name ("Имя проекта") и укажите путь, например, в вашем основном каталоге, как местоположение проекта.

Установите флажок "Использовать отдельную папку для хранения библиотек" и укажите местоположение папки библиотек (необязательно). Дополнительная информация приведена в статье Предоставление доступа к библиотеке другим пользователям в документе Разработка приложений с помощью NetBeans IDE.

Удалите флажок "Create Main Class", если он установлен.

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

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

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

В окне 'Проекты' щелкните правой кнопкой мыши узел NumberAddition и выберите Создать > Другие .

Введите NumberAdditionUI в качестве имени класса.

Выберите пакет my.numberaddition .

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

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

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

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

Figure1

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

Для начала выберите панель из категории Swing Containers ("Контейнеры Swing") в палитре и перетащите ее на JFrame.

В диалоговом окне "Border" выберите "TitledBorder" из списка и введите Number Addition в поле "Title". Для сохранения изменений и закрытия диалогового окна нажмите кнопку "OK".

Теперь на экране должен отображаться пустой элемент "JFrame" с заголовком "Number Addition", как показано на рисунке. Согласно рисунку добавьте к нему три метки JLabel, три текстовых поля JTextField и три кнопки JButton.

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

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

Дважды щелкните jLabel1 и измените ntrcn (свойство "text") на First Number .

Дважды щелкните jLabel2 и измените текст на Second Number .

Дважды щелкните jLabel3 и измените текст на Result .

Удалите стандартный текст из jTextField1 . Отображаемый текст можно преобразовать в редактируемый. Для этого щелкните правой кнопкой мыши текстовое поле и выберите 'Редактировать текст' во всплывающем меню. При этом может потребоваться восстановить первоначальный размер поля jTextField1 . Повторите это действие для полей jTextField2 и jTextField3 .

Измените отображаемый текст jButton1 на Clear . (Для изменения текста кнопки щелкните кнопку правой кнопкой мыши и выберите "Edit Text". В качестве альтернативы можно щелкнуть кнопку, выдержать паузу и щелкнуть еще раз.)

Измените отображаемый текст jButton2 на Add .

Измените отображаемый текст jButton3 на Exit .

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

Figure2

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

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

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

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

Щелкните правой кнопкой мыши кнопку "Exit". Во всплывающем меню выберите Events ("События") > Action ("Действие") > actionPerformed. Учтите, что меню содержит множество других событий, на которые может реагировать программа! При выборе события actionPerformed среда IDE автоматически добавит прослушиватель ActionListener к кнопке Exit ("Выход") и создаст метод обработчика для обработки метода прослушивателя actionPerformed.

В среде IDE автоматически открывается окно "Source Code", где отображается место вставки действия, которое должно выполняться кнопкой при ее нажатии (с помощью мыши или клавиатуры). Окно "Source Code" должно содержать следующие строки:

Теперь добавим код действия, которое должна выполнять кнопка "Exit". Замените строку TODO на System.exit(0); . Готовый код кнопки "Exit" должен выглядеть следующим образом:

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

Щелкните вкладку "Design" в верхней части рабочей области для возврата к экрану "Form Design".

Щелкните правой кнопкой мыши кнопку "Clear" ( jButton1 ). В появившемся меню выберите "Events > Action > actionPerformed".

Нажатие кнопки "Clear" должно приводить к удалению всего текста из всех текстовых полей "jTextField". Для этого следует добавить код, аналогичный приведенному выше. Готовый исходный код должен выглядеть следующим образом:

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

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

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

Сначала она принимает данные, введенные пользователем в полях jTextField1 и jTextField2 , и преобразовывает их из типа "String" в тип "Float".

Затем она выполнит сложение двух чисел.

И, наконец, она преобразует сумму в тип String и поместит ее в jTextField3 . Начнем!

Щелкните вкладку "Design" в верхней части рабочей области для возврата к экрану "Form Design".

Щелкните правой кнопкой мыши кнопку "Add" ( jButton2 ). Во всплывающем меню выберите Events ("События") > Action ("Действие") > actionPerformed.

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

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

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

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

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

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

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

Для сборки архива JAR приложения выберите "Run > Clean and Build Main Project" (Shift-F11).

При помощи проводника по файловой системе или диспетчера файлов перейдите в каталог ` NumberAddition/dist`.

Примечание. Местоположение каталога проекта NumberAddition зависит от пути, указанного при создании проекта в шаге 3 в разделе Упражнение 1. Создание проекта.

Дважды щелкните файл NumberAddition.jar .

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

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

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

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

Вызовите командную строку или окно терминала.

В командной строке измените текущий каталог на каталог NumberAddition/dist .

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

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

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

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

Вернитесь к файлу NumberAdditionUI.java в редакторе. Щелкните вкладку "Design" для просмотра структуры графического интерфейса в GUI Builder.

Щелкните правой кнопкой мыши любой элемент графического интерфейса и выберите "Events" в появившемся меню. Теперь можно просто изучить содержимое меню, не выбирая каких-либо пунктов.

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

Приложение также может реагировать на нажатие клавиш, одинарный, двойной или тройной щелчок мышью, перемещение указателя мыши, изменение размера окна и перемещение фокуса ввода. Меню "Events" позволяет автоматически создать обработчики событий для всех этих событий. Наиболее распространенным из них является событие "Action". (Для получения дополнительных сведений см. практические рекомендации по обработке событий в руководстве Sun Java Events Tutorial.)

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

Вернитесь к файлу NumberAdditionUI.java в редакторе. Щелкните вкладку "Source" для просмотра исходного кода графического интерфейса.

Выполните прокрутку вниз и просмотрите реализованные методы jButton1ActionPerformed() , jButton2ActionPerformed() и jButton3ActionPerformed() . Эти методы называются обработчиками событий.

Теперь перейдите к методу initComponents() . Если этот метод отсутствует, найдите строку Generated Code и щелкните знак + рядом с этой строкой для отображения скрытого метода initComponents() .

Обратите внимание на синий блок, окружающий метод initComponents() . Этот код был автоматически создан средой IDE и не может быть изменен пользователем.

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

В методе initComponents() найдите следующий фрагмент:

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

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

Объединение всех этих компонентов создает графический интерфейс пользователя.

Что такое Swing в Java?

Создавать приложения становится проще, поскольку у нас уже есть компоненты GUI, такие как кнопка, флажок и т. д.

Контейнерный класс

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

Ниже приведены три типа контейнерных классов:

Разница между AWT и Swing

Иерархия

иерархия swing

Объяснение: Все компоненты в свинге, такие как JButton, JComboBox, JList, JLabel, унаследованы от класса JComponent, который можно добавить в классы контейнера.

JButton Class

Он используется для создания помеченной кнопки. Использование ActionListener приведет к некоторым действиям при нажатии кнопки. Он наследует класс AbstractButton и не зависит от платформы.

JTextField Class

Он наследует класс JTextComponent и используется для редактирования однострочного текста.

создание поля редактируемого текста

JScrollBar Class

Он используется для добавления полосы прокрутки, как горизонтальной, так и вертикальной.

пример JScrollBar

JPanel Class

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

компонент JPanel

JMenu Class

Он наследует класс JMenuItem и является компонентом выпадающего меню, которое отображается из строки меню.

выпадающее меню

Вывод:

Класс JList

Он наследует класс JComponent, объект класса JList представляет список текстовых элементов.

Класс JList

Вывод:

JLabel Class

Используется для размещения текста в контейнере. Он также наследует класс JComponent.

размещение текста в контейнере

Вывод:

JComboBox Class

Он наследует класс JComponent и используется для отображения всплывающего меню выбора.

отображения всплывающего меню java

Вывод:

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

Макет границы

Макет потока

Макет потока

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

GridBag Layout

GridBagLayout размещает компоненты в сетке

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

Пример: фрейм чата

чат на Java пример

Это простой пример создания GUI с использованием Swing в Java.

Средняя оценка / 5. Количество голосов:

Спасибо, помогите другим - напишите комментарий, добавьте информации к статье.

Как создать графический интерфейс с JavaFX, используя разметку FXML и SceneBuilder.

Все посты в серии о JavaFX:

Традиционный способ

Просто напоминание — код выглядел так:


Как видите весь пользовательский интерфейс создан в Java коде.

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

У класса явно нет единой ответственности. Сравните это, например, с веб-интерфейсом, где каждая страница имеет четко разделенные задачи:

  • HTML — это структура
  • CSS — это визуальные эффекты
  • JavaScript — это поведение

Представляем FXML

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

В действительности есть много шаблонов дизайна для этого. Как правило, в конечном итоге вы приходите к варианту «Model-View-Whatever» — это что-то вроде «Model View Controller», «Model View Presenter» или «Model View ViewModel».

Можно часами обсуждать плюсы и минусы разных вариантов — давайте не будем делать это здесь. Более важно то, что с JavaFx вы можете использовать любой из них.

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

Оказывается иерархическая структура XML — это отличный способ описать иерархию компонентов в пользовательском интерфейсе. HTML работает достаточно хорошо, верно?

Формат XML, специфичный для JavaFX, называется FXML. В нем вы можете определить все компоненты приложения и их свойства, а также связать их с контроллером, который отвечает за управление взаимодействиями.

Загрузка FXML файлов

Итак, как мы можем изменить наш метод запуска для работы с FXML?


Здесь root представляет корневой компонент вашего пользовательского интерфейса, остальные компоненты вложены в него.

Метод load имеет generic возвращаемое значение, поэтому вы можете указать конкретный тип, а не Parent. Далее, вы получаете доступ к компонентно-ориентированным методам. Однако, это делает ваш код более хрупким. Если вы измените тип корневого компонента в вашем FXML, приложение может перестать работать во время выполнения, но при этом во время компиляции не будет ошибок. Это происходит потому, что теперь есть несоответствие типа, объявленного в вашем FXML и в загрузчике Java FXML.

Создание FXML файла

Теперь мы знаем, как загрузить файл FXML, но нам все еще нужно его создать. Файл должен иметь расширение .fxml. В Maven проекте, вы можете поместить этот файл в папку ресурсов или FXMLLoader может загрузить его с внешнего URL-адреса.

После создадания файла в его первой строке необходимо ввести декларацию XML:

Импорт

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

Хорошей новостью является то, что вместо добавления всех операторов импорта вручную, ваша IDE должна помочь вам добавить импорт аналогично добавлению их в классы Java.

Добавление компонентов

Теперь пришло время добавить некоторые компоненты. В предыдущей статье мы узнали, что каждая сцена может иметь только один дочерний компонент. Для начала давайте добавим простую метку (label):


Конечно, метка в качестве корневого компонента — это не очень реалистичный пример. Обычно предпочтительнее использовать какой-то макет (layout), который является контейнером для нескольких компонентов и организует их расположение. Мы рассмотрим макеты позже в этой серии, а сейчас давайте просто воспользуемся простым VBox, который размещает свои дочерние элементы вертикально друг над другом.

FX Namespace

Существует пара элементов и атрибутов FXML, которые по умолчанию недоступны. Вам нужно добавить пространство имен (Namespace) FXML, чтобы сделать их доступными. Его необходимо добавить к корневому компоненту:


Теперь можно использовать новые элементы из пространства имен fx. Давайте попробуем добавить уникальные идентификаторы в наши компоненты:


Атрибут fx:id является уникальным идентификатором компонента, который можно использовать для ссылки на компонент из других частей нашего FXML и даже из нашего контроллера.

Скрипты

Наше приложение пока статично. Есть несколько меток и кнопка, но приложение не делает ничего динамического.

Давайте отреагируем на нажатие нашей кнопки и изменим заголовок с «Click me!» на «Click me again!».

Первое, что нужно сделать, это добавить обработчик события onAction для нашей кнопки.


Обратите внимание на fx:id, это идентификатор, который будет использоваться позже для ссылки на кнопку.

Теперь нужно предоставить функцию, которая будет вызвана для обработки события. Ее можно определить внутри тега fx:script. Важно то, что вы можете использовать различные языки для написания скрипта, JavaScript, Groovy или Clojure. Давайте посмотрим пример на JavaScript:


Заметьте, что мы ссылаемся на наш компонент Button с помощью идентификатора mainButton, который был объявлен так:


Также необходимо указать, какой язык сценариев вы используете в файле FXML:


Давайте рассмотрим полный текст примера:


Должен ли я использовать это?

В приведенном выше примере показано, как ссылаться на компоненты с помощью fx:id и как добавить простое поведение с помощью скрипта на JavaScript. Неужели это то, что вы должны на самом деле делать?

Ответ — в большинстве случаев нет. Есть несколько проблем с таким подходом. Причина, по которой введен FXML, была разделение интересов — чтобы отделить структуру и поведение пользовательского интерфейса. В этом скрипте снова вернулось поведение слитное со структурой пользовательского интерфейса. Более того, поскольку мы больше не работаем с кодом Java, а с XML, были утрачены все проверки кода во время компиляции и безопасность типов. Теперь все проблемы в приложении будут обнаружены во время выполнения, а не во время компиляции. Приложение стало очень хрупким и подверженым ошибкам.

Добавление контроллера

Итак, что можно сделать, чтобы получить четкое разделение интересов? Можно связать контроллер с нашим файлом FXML. Контроллер — это Java класс, который отвечает в приложении за обработку поведения и взаимодействия с пользователем. Таким образом можно вернуть безопасность типов и проверки времени компиляции.

Контроллер является POJO, он не должен расширять или реализовывать что-либо, а также не должен иметь никаких специальных аннотаций.

Как можно связать класс контроллера с нашим FXML? По существу, есть два варианта.

На Java

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

В FXML

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


Если вы объявляете свой класс Controller в FXML, он автоматически создается для вас. Этот подход имеет одно ограничение — в контроллере нужно создать конструктор без аргументов, чтобы позволит легко создавать новый экземпляр класса Controller.

Для получения доступа к экземпляру контроллера, созданного автоматически, можно использовать загрузчик FXML:

Вызов методов контроллера

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


При нажатии на кнопку, она вызывает метод MainSceneController.buttonClicked(). Имейте в виду, что это работает, только если метод объявлен public. Если модификатор доступа более строгий, необходимо аннотировать метод аннотацией @FXML.

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

Пока что мы просто печатаем на консоль. Что если мы снова захотим изменить текст нашей кнопки на «Click me again»? Как мы можем получить ссылки на компоненты в нашем контроллере?

К счастью, это легко. Помните эти атрибуты fx:id?


JavaFX пытается автоматически сопоставить компоненты с fx:id с полями определенным в вашем контроллере с тем же именем.

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


JavaFX пытается внедрить объект кнопки в ваш контроллер в поле с именем mainButton:


Как и в предыдущих методах, ваши поля должны быть public или аннотированными @FXML.

Теперь, когда у нас есть ссылка на нашу кнопку, можно легко изменить ее текст:

Scene Builder

Написание вашей структуры GUI в XML может быть более естественным, чем в Java (особенно если вы знакомы с HTML). Тем не менее, до сих пор это не очень удобно. Хорошей новостью является то, что существует официальный инструмент под названием Scene Builder, который поможет вам в создании пользовательского интерфейса. В двух словах, это графический редактор для вашего графического интерфейса.


В редакторе имеется три основных области:

  1. В левой части отображаются доступные компоненты, которые можно перетащить в среднюю часть. Она также содержит иерархию всех компонентов в вашем пользовательском интерфейсе, поэтому вы можете легко перемещаться по ней.
  2. Средняя часть — это ваше приложение, отображаемое на основе вашего файла FXML.
  3. Справа находится инспектор текущих компонентов. Здесь вы можете редактировать различные свойства выбранного текущего компонента. Любой компонент, выбранный в средней части иерархии, отображается в инспекторе.

Standalone

Scene Builder можно загрузить как отдельное приложение, которое можно использовать для редактирования FXML файлов.

Интеграция с IntelliJ IDEA

В качестве альтернативы, Scene Builder предлагает интеграцию с IDE.

В IntelliJ IDEA вы можете нажать правой кнопкой мыши на любом FXML файле и затем выбрать опцию меню «Открыть» в SceneBuilder.

В качестве альтернативы, IntelliJ IDEA интегрирует SceneBuilder непосредственно в IDE. Если вы откроете файл FXML в IDEA, в нижней части экрана появятся две вкладки


В IntelliJ IDEA можто настроить расположение исполняемого файла SceneBuilder:

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

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

Достоинства:

  • часть JDK;
  • скорость работы;
  • графические компоненты похожи на стандартные.

Недостатки:

  • использование нативных компонентов налагает ограничения на использование их свойств. Некоторые компоненты могут вообще не работать на «неродных» платформах;
  • некоторые свойства, такие как иконки и всплывающие подсказки, в AWT вообще отсутствуют;
  • стандартных компонентов AWT очень немного, программисту приходится реализовывать много кастомных;
  • программа выглядит по-разному на разных платформах (может быть кривоватой).

заключение:

В настоящее время AWT используется крайне редко — в основном в старых проектах и апплетах. Oracle припрятал обучалки и всячески поощряет переход на Swing. Оно и понятно, прямой доступ к компонентам оси может стать серьезной дырой в безопасности.

Как выглядит Swing

Как выглядит Swing

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

Тем не менее благодаря простоте использования, богатой документации и гибкости компонентов Swing стал, пожалуй, самым популярным графическим фреймворком в Java. На его базе появилось много расширений, таких как SwingX, JGoodies, которые значительно упрощают создание сложных пользовательских интерфейсов. Практически все популярные среды программирования Java включают графические редакторы для Swing-форм. Поэтому разобраться и начать использовать Swing не составит особого труда.

Достоинства:

Недостатки:

  • окно с множеством компонентов начинает подтормаживать;
  • работа с менеджерами компоновки может стать настоящим кошмаром в сложных интерфейсах.

Заключение:

Swing жил, Swing жив, Swing будет жить. Хотя Oracle и старается продвигать JavaFX, на сегодняшний день Swing остается самым популярным фреймворком для создания пользовательских интерфейсов на Java.

Как выглядит SWT

Как
выглядит
SWT

SWT был разработан в компании IBM в те времена, когда Swing еще был медленным, и сделано это было в основном для продвижения среды программирования Eclipse. SWT, как и AWT, использует компоненты операционной системы, но для каждой платформы у него созданы свои интерфейсы взаимодействия. Так что для каждой новой системы тебе придется поставлять отдельную JAR-библиотеку с подходящей версией SWT. Это позволило более полно использовать существующие функции компонентов на каждой оси. Недостающие функции и компоненты были реализованы с помощью 2D, как в Swing. У SWT есть много приверженцев, но, положа руку на сердце, нельзя не согласиться, что получилось не так все просто, как хотелось бы. Новичку придется затратить на изучение SWT намного больше времени, чем на знакомство с тем же Swing. Кроме того, SWT возлагает задачу освобождения ресурсов на программиста, в связи с чем ему нужно быть особенно внимательным при написании кода, чтобы случайное исключение не привело к утечкам памяти.

Достоинства:

  • использует компоненты операционной системы — скорость выше;
  • Eclipse предоставляет визуальный редактор форм;
  • обширная документация и множество примеров;
  • возможно использование AWT- и Swing-компонентов.

Недостатки:

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

Заключение:

Видно, что в IBM старались. Но получилось уж очень на любителя…

Как выглядит JavaFX

Как выглядит JavaFX

JavaFX можно без преувеличения назвать прорывом. Для отрисовки используется графический конвейер, что значительно ускоряет работу приложения. Набор встроенных компонентов обширен, есть даже отдельные компоненты для отрисовки графиков. Реализована поддержка мультимедийного контента, множества эффектов отображения, анимации и даже мультитач. Внешний вид всех компонентов можно легко изменить с помощью CSS-стилей. И самое прекрасное — в JavaFX входит набор утилит, которые позволяют сделать родной инсталлятор для самых популярных платформ: exe или msi для Windows, deb или rpm для Linux, dmg для Mac. На сайте Oracle можно найти подробную документацию и огромное количество готовых примеров. Это превращает программирование с JavaFX в легкое и приятное занятие.

Достоинства:

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

Недостатки:

  • фреймворк еще разрабатывается, поэтому случаются и падения и некоторые глюки;
  • JavaFX пока не получил широкого распространения.

Заключение:

Хорошая работа, Oracle. Фреймворк оставляет только позитивные впечатления. Разобраться несложно, методы и интерфейсы выглядят логичными. Хочется пользоваться снова и снова!

SWT: погодный виджет

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

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

Любая программа на SWT начинается с создания объекта Display. Он служит своеобразным контекстом приложения, который содержит необходимые методы для обращения к ресурсам системы и обеспечивает цикл событий. Следующим шагом будет создание не менее важного объекта Shell. Shell представляет собой обычное окно операционной системы. В конструктор shell передается Display, чтобы создать окно верхнего уровня.

Так как мы создаем виджет, нам не нужно отображать стандартное обрамление окна и кнопки управления, для этого мы указали флаг NO_TRIM. Для фона мы будем использовать картинку — прямоугольник с закругленными углами. В принципе, окно SWT может принимать любые формы. Чтобы добиться такого эффекта, используем класс Region. Все, что нужно, — добавить в этот класс все видимые точки из картинки фона, пропуская прозрачные.

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

Устанавливаем форму окна:

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

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

Назначим слушатель соответствующим событиям окна:

Устанавливаем размер окна равным размеру изображения:

Открываем окно и запускаем цикл событий:

Не забываем в конце освободить использованные ресурсы:

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

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

Для расположения графических компонентов в окне в нужном виде используются менеджеры компоновки. Менеджер компоновки занимается не только расположением компонентов, но и изменением их размеров при изменении размеров окна. Для нашего виджета будем использовать GridLayout. Этот менеджер располагает компоненты в ячейках воображаемой таблицы. Создаем GridBagLayout на две колонки с различной шириной колонок (флаг false в конструкторе), устанавливаем его в качестве менеджера компоновки окна:

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

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

В SWT нет прозрачного фона компонентов, и позади картинки статуса будет красоваться белый фон, чего, конечно, не хотелось бы. Поэтому создадим объект Color с цветом фона окна:

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

Теперь добавим Label с текущей температурой и расположим его в правой верхней части окна:

Установим какую-нибудь температуру:

Для записи температуры по Цельсию используется юникодный номер соответствующего символа со служебными символами \u.

Шрифт по умолчанию для текстовых меток слишком маленький. Так что создадим новый, побольше:

FontData[] fD = temperatureLabel.getFont().getFontData(); fD[0].setHeight(30); fD[0].setStyle(SWT.BOLD); Font newFont = new Font(display, fD[0]); temperatureLabel.setFont(newFont); Шрифт, как и другие ресурсные объекты, нужно освобождать. Для этого воспользуемся слушателем события разрушения метки:

Наконец, добавим метку с описанием погодных условий:

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

Виджет погоды

Виджет погоды

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

На Swing мы напишем виджет для отображения RSS-новостей. Начинаем, как и в прошлый раз, с создания окна. Класс, реализующий функционал стандартного окна в Swing, называется JFrame. По умолчанию закрытие окна приложения в Swing не приводит к остановке программы, так что лучше прописать, как должно себя вести окно при закрытии:

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

Для хранения информации о доступных новостях заведем класс FeedMessage c полями для названия статьи и даты выхода:

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

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

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

Теперь займемся внешним видом ячеек. Swing позволяет назначать отдельные классы представления для разных типов данных. За отрисовку отдельных ячеек таблицы отвечает класс, наследующий интерфейс TableCellRenderer. По умолчанию используется DefaultTableCellRenderer, который представляет собой текстовую метку.

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

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

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

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

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

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

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

Теперь поменяем форму окна на прямоугольник с закругленными углами. Лучше всего это делать в слушателе компонента, так как, если размер окна изменится, форма окна будет правильно пересчитана:

Устанавливаем размер окна, убираем обрамление и делаем окно полупрозрачным.

Наконец, открываем окно в графическом потоке. SwingUtilities.invokeLater(new Runnable() < public void run() < frame.setVisible(true); >>);

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

Виджет новостей

Виджет новостей

И наконец, гвоздь сезона — JavaFX. Воспользуемся его мультимедийными возможностями и компонентом для построения графиков и сделаем простенький эквалайзер.

Для начала наследуем класс виджета от Application. Это основной класс приложения в JavaFX. Application содержит основные методы жизненного цикла приложения. Компоненты формы создаются в методе start, аргументом которому служит класс Stage. Stage представляет собой окно программы. Изменим стиль окна на TRANSPARENT, чтобы убрать обрамление и кнопки. В Stage помещается класс Scene, в котором задаются размеры окна и цвет фона. В Scene, в свою очередь, передаем класс Group, в который будем помещать дочерние компоненты:

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

Заполняем диаграмму начальными данными:

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

Добавляем оба компонента к группе:

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

Загружаем песню в плеер:

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

Делаем сцену видимой и запускаем песню:

И наслаждаемся такой вот красотой.

Простой эквалайзер

Простой эквалайзер

Как видишь, остается все меньше того, что не под силу Java. Кроме описанных графических библиотек, есть еще множество других, не таких распространенных, но не обязательно худших по качеству. У каждой из них есть свои сильные и слабые стороны. Java предоставляет право выбора тебе :).

Читайте также: