Как запустить javafx приложение
Это руководство ознакомит с основными понятиями JavaFX, примерами кода, которые вы можете использовать в качестве шаблона для своих собственных первых приложений.
Класс приложения
Приложение JavaFX нуждается в основном классе запуска. Этот класс должен расширять класс javafx.application.Application, который является стандартным в Java начиная с 8 версии.
Вот пример подкласса:
Реализация start()
Все подклассы класса JavaFXApplication должны реализовывать абстрактный метод start() класса Application (или быть абстрактным его подклассом).
Метод вызывается при запуске приложения:
Метод start() принимает один параметр типа Stage. На этапе отображаются все визуальные части приложения. Объект Stage создается для вас во время выполнения JavaFX.
Приведенный выше пример устанавливает заголовок для объекта stage, а затем вызывает show() для него. Это сделает приложение видимым в окне с заголовком, видимым в верхней панели окна.
Если вы не вызываете show() на объекте stage, ничего не видно. Окно не открывается. Если ваше приложение не становится видимым при запуске, проверьте, не забыли ли вы вызвать метод Stage show() изнутри start().
Добавление метода main()
На самом деле вы можете запустить приложение без метода main(). Но если хотите передать параметры командной строки в приложение, вам нужно добавить его:
Метод launch() определит, из какого класса он вызывается, поэтому не нужно явно указывать это.
Вот скриншот окна, открываемого в результате запуска вышеуказанного приложения:
Добавление Scene
Предыдущие примеры JavaFX только открывают окно, но внутри этого окна ничего не отображается. Чтобы отобразить что-то внутри окна приложения JavaFX, вы должны добавить Scene к объекту Stage. Это делается внутри метода start().
Все компоненты, которые должны отображаться в приложении, должны находиться внутри сцены. Названия «Scene» и «Stage» вдохновлены театром. Stage может отображать несколько scene, как в театральной постановке. Аналогичным образом, компьютерная игра может иметь сцену меню, игровую сцену, сцену рекордов и т. д.
Вот пример того, как добавить объект Scene в рабочую область вместе с простой меткой:
Три строки были добавлены к этому примеру. Сначала создается объект Label. Затем создается объект сцены, передавая метку как параметр вместе с двумя параметрами, представляющими ширину и высоту ее.
Параметры width и height устанавливают ширину и высоту окна JavaFX, когда оно открывается, но размер окна может быть изменен пользователем.
Это второй пост в серии о JavaFX. Вы можете прочитать в первой статье о том, как настроить вашу среду для разработки JavaFx.
Все посты в серии о JavaFX:
Структура приложения
Каждое приложение состоит из иерархии нескольких основных компонентов: Stages (окна), (сцены) и nodes (узлы). Давайте рассмотрим каждую из них.
Stage
Stage по существу представляет собой окно. Ваше приложение может иметь несколько компонент stage, но как минимум одна должна быть обязательно.
Scene
Scene отображает содержание сцены (stage). Каждая компонента stage может содержать несколько компонент scene, которые можно переключать. Представьте себе театральные подмостки, на которых сменяются несколько сцен во время спектакля.
Каждая компонента stage может содержать различные компоненты, называемые узлами (node). Узлы могут быть элементами управления, такими как кнопки или метки, или даже макетами (layout), которые могут содержать несколько вложенных компонентов. Каждая сцена (scene) может иметь один вложенный узел (node), но это может быть макет (layout), который может содержать несколько компонентов. Вложенность может быть многоуровневой — макеты могут содержать другие макеты и обычные компоненты.
Резюме
Каждое приложение может иметь несколько окон (Stage). Каждая компонента Stage может переключать несколько Scene (сцен). Сцены содержат узлы (node) — макеты и обычные компоненты.
Эту иерархию можно визуализировать следующим образом:
Теперь давайте посмотрим на конкретный пример — реальное приложение.
Класс Application
Время начать программировать. Если вы следовали предыдущей статье, у вас уже готовы все необходимые зависимости.
Каждое приложение JavaFX должно иметь класс main, который расширяет класс:
Кроме того, необходимо переопределить абстрактный метод из класса Application:
Касс main выглядит примерно так:
Метод main
Для запуска JavaFx приложения не обязательно нужен метод main(). Вы можете упаковать исполняемый файл jar, используя JavaFX Packager Tool. Однако гораздо удобнее иметь метод main.
При этом приложение не только легче запустить, но в него можно как обычно передавать параметры командной строки.
Внутри метода main() приложение можно запустить используя метод:
Легко заметить, что это статический метод в классе Application. Мы не указали основной класс, но JavaFX может определить это автоматически в зависимости от класса, который вызывает этот метод.
Настройка Stage
Теперь мы знаем как запустить наше приложение, используя метод main(). Тем не менее, ничего не произойдет, если мы сделаем это. Нужно окно, которое мы хотим показать. Окно называется stage, помните? На самом деле, у нас уже есть первичная stage, переданная в метод start в качестве входного параметра:
Мы можем использовать эту компоненту stage. Единственная проблема в том, что она скрыта по умолчанию. К счастью, мы можем легко показать ее, используя метод primaryStage.show():
Теперь, когда вы запустите приложение, вы должны увидеть следующее окно:
Не очень впечатляет, правда? Во-первых, давайте добавим хорошую подпись к нашему окну.
Чтобы окно выглядело еще лучше, давайте добавим красивую иконку в верхнюю панель окна:
Вы можете добавить несколько иконок, представляющих приложение. Точнее одну и ту же иконку разных размеров. Это позволит использовать иконку походящего размера в зависимости от контекста приложения.
Теперь можно настроить свойства и поведение объекта Stage, например:
- Установить положение с помощью setX() и setY()
- Установить начальный размер с помощью setWidth() и setHeight()
- Ограничить максимальные размеры окна с помощью setMaxHeight() и setMaxWidth() или отключить изменение размера с помощью setResizable(false)
- Установить режим окно всегда сверху, используя setAlwaysOnTop()
- Установить полноэкранный режим, используя setFullScreen()
Однако для запуска конструктора сцены требуется указать дочерний узел. Давайте сначала создадим простую метку (label). Затем мы создаем сцену (scene) этой меткой (label) в качестве дочернего узла.
Вы заметили, что Scene допускает только один дочерний компонент. Что если нам нужно больше? Необходимо использовать layout (макет), который является компонентом, который может включать несколько дочерних элементов и размещать их на экране в зависимости от используемого layout (макета). Мы рассмотрим макеты позже в этой серии статей.
Чтобы сделать приложение немного более визуально привлекательным, давайте разместим метку в центре экрана.
Наконец, нам нужно установить Scene для Stage, которая у нас уже есть:
Хотя есть и разные версии под разные java, желательно выбрать соответствующую вашей. Например, у нас в компьютерном классе всюду java 8, поэтому лучше скачать 8 версию.
Восьмая версия еще особенно хороша тем что ей не надо админских прав и можно ставить в компьютерных классах
по завершению установки запустится SceneBuilder
но он нам пока не нужен, так что можно его закрыть.
Делаем новый проект типа JavaFX
назову его CustomTypeGUI
получаем такую структуру проекта:
Принцип организации javafx интерфейса
Кликнем дважды на файлик sample.fxml чтобы открыть его и увидим там что-то такое:
fxml – это такой аналог html, только в рамках java, тут даже есть всякие импорты. И есть тэги, определяющие что будет отображаться. Тут к нас пока только один тэг GridPane, которые используется для выравнивания компонент по сетке.
Правда пока выравнивать нечего, так что пока это по сути пустой контейнер.
Особо стоит обратить внимание на атрибут fx:controller в нем указан класс вместе с полным путем, в котором мы будем писать код для интерфейса.
И так, попробуем запустить программу. Увидим что-то такое
Откуда же это все взялось? А на самом деле ничего хитрого нет. Открываем файлик Main.java и видим
Добавляем кнопку
Вернемся к файлу sample.fxml. Теперь запустим SceneBuidler, выбираем Open Project
и открываем наш файлик. Увидим что-то такое
Перетянем теперь кнопку на форму. Так как пока у нас пустой GridPane наша форма выглядит как пустота. Но тянуть можно:
Сохраним перетянутое Ctrl+S и переключимся обратно в Idea. И глянем что у нас выросло с файлике sample.fxml. Там у нас будет такое:
Видим, что тут много чего поменялось. Появились какие-то Constraints (это так называем ограничения на размеры колонок и строк, нам они пока не интересны).
Ну и главное, что тут появился тег children и внутри него наша кнопочка
- text – это то что написано на кнопке
- mnemonicParsing – это специальный тег для обработки горячих клавиш, но нам это сейчас неинтересно, так что можно игнорировать
Можно попробовать запустить:
ура, есть кнопочка! =)
Добавляем реакцию на нажатие
Но кнопка — это не кнопка если нажимая на нее ничего не происходит. Попробуем добавить реакцию на клик.
Переключимся на файл Controller.java:
Помните я упомянул атрибут fx:controller=”sample.Controller” внутри sample.fxml, так вот мы сейчас в том самом классе на который указывал этот атрибут. За счет него происходит связывание интерфейса и логики (контроллера).
Чтобы добавить реакцию на клик достаточно сделать следующие операции.
Можно даже попробовать запустить. И потыкать кнопку
хехе, очевидно ничего не произойдет. Мы ж пока функцию не привязали =)
А теперь переключимся на SceneBuilder и привяжем кнопку к функции
не забудем сохранить, и запустим проект по-новому
Кстати можно открыть файлик sample.fxml и глянуть что там произошло:
Читаем значение из текстового поля
Ну тыкать на кнопочки и выполнять всякие функции — это конечно важное умение. Но не менее важно уметь считать значение из поля, например, текстового.
Делается это в некотором роде проще чем привязка кнопки.
Например, хочу я добавить поле для ввода текста, и чтобы по нажатию на кнопку выводилось содержимое этого поля.
Что я сделаю? Сначала создам в классе поле, через которое образуется связь
теперь переключимся на SceneBuilder, перетащим текстовое поле на форму, а затем привяжем его к нашему классу, путем указания свойства fx:id:
если вдруг у вас в этом поле ничего не высветилось, то можете смело вписать туда вручную txtInput.
Сохраним в SceneBuilder и вернемся обратно в Idea. Если глянуть в файлик fxml то увидим
теперь вернемся в наш Controller и подправим метод showMessage:
Меняем значения текстового поля
О, давайте еще научимся изменять значение в списке, но тут все просто
В принципе вот и вся наука =)
- добавил поле в контроллер
- добавил объект в SceneBuilder
- связал через fx:id, либо связал с методом.
Теперь можно пилить что-нибудь посложнее.
Наверное, не будем рассматривать как делать конкретно приложение под вашу задачку. Все-таки в прошлом году мы уже пилили интерфейсы. И принцип должен быть понятен.
Но, очевидно, полезно рассмотреть, как можно добавлять разные компоненты и заставить их реагировать на ваши данные.
К тому же в JavaFX есть много хитрых особенностей, которые в WindowsForms не встречалось.
И так, попробуем добавить выпадающий список. Действуем по выше предложенному алгоритму. Сперва добавим поле в контроллер:
теперь добавляем на форму
затем подключаем по fx:id
не забываем сохраниться в SceneBuilder.
Запускаем и проверяем:
Ура! Есть список! Правда пустой пока…
Заполняем список (интерфейс Initializable)
И вот незадача, как же его заполнить? У нас по сути голый класс Controller, без ничего. Давайте попробуем в конструкторе:
запускаем и… бдыщь
суть стенаний виртуальной машины заключается в том, что comboBox нулевой. А нулевой он потому что привязка полей помеченных декоратором @FXML происходит уже после вызова конструктора, где-то в терньях фреймворка JavaFX.
Поэтому добавление элемента в конструкторе не прокатит.
Что ж делать? Оказывается все просто! Надо наследоваться от некого интерфейса Initializable и переопределить одну функцию, которую используется как своего конструктор формы. Делается это так
загоним теперь в метод initialize наш вызов добавления элемента
Добавляем реакцию на переключения списка
Давайте сначала добавим еще несколько элементов
Есть как минимум два способа добавить реакцию на переключения
Через SceneBuilder
не забываем сохраниться.
2) Затем в IDEA тыкаем правой кнопкой мыши на название метода
выбираем первый пункт Show Context Actions, а затем:
3) Нас перекинет в контроллер где мы увидим новодобавленный метод
в принципе, его можно было и руками добавить >_>
Этот метод будет вызываться каждый раз, когда мы будем переключать элемент списка. Давайте чего-нибудь там будем выводить:
Через лямбда-функцию
Ну тут просто в методе инициализации привязываете лямбда-функцию к реакции на изменение свойства.
Я на лекции расскажу что тут происходит на самом деле
Еще может пригодится чекбокс, для вывода всяких булевых значений. Добавим его на форму
добавим в Controller:
теперь подключим checkbox к форме
ну теперь мы можем, например, управлять им кликая на кнопку:
ой, забыли кнопке указать другую функцию
Вот теперь красота! =)
кстати если хотите текст поменять то правьте поле Text:
Одним из важных принципов при разработке приложений, а особенно GUI приложений заключается в том, что состояние формы (значения в полях, размеры и положение) после закрытия приложения и при последующем открытии должно сохранятся.
Как правило для хранения состояния приложения используют простые файлы в каком-нибудь распространённом формате типа *.xml, *.ini, *.json
Выбор моментов фиксации самого состояние остается на совести разработчика, это может быть момент сразу после изменения значений в полях, может быть реакцией на клик какой-нибудь кнопки (в идеале чем чаще, тем лучше), а может быть просто момент закрытия формы.
Подключаем обработчик закрытия формы
Мы будем сохранять в момент закрытия формы.
Вот мы недавно уже мучались с поиском момента создания формы, теперь так же помучаемся с определением момента закрытия формы.
К сожалению, тут простым интерфейсом не отделаешься. Вообще в JavaFX нет как такового понятия формы.
Там есть понятие stage (англ. состояние, сцена как место где происходят события), которое представляет собой окно приложения и scene (англ. тоже сцена, но уже в качестве события) которая, если немного упростить, представляет собой fxml файлик + контроллер.
Ну и ясно что именно к scene привязывается класс Controller. И так как scene за окно формы (то бишь stage) не отвечает, то из него и нельзя получить прямого доступа к событию закрытия окна.
Но можно получить не прямой. Для этого надо поймать событие закрытия формы (то бишь stage) и проксировать его в Controller. Делается это так:
Сначала пойдем в контроллер и создадим функцию которая должна будет вывязываться при закрытии формы. Такую:
теперь идем в Main и делаем магические пассы:
Сохраняем состояние формы в файл
И так, хотя данные на форме и так уже имеют привязанные поля, и можно считывать значения сразу с формы и сразу куда-то писать мы так делать не будем. Потому что в этом случае нам самим придется организовывать запись в файл, а затем еще учится парсить результат обратно. В общем, в современной разработке, это такой себе подход. Да и в прошлом семестре мы этого и так наелись.
Поэтому мы создадим класс который будет хранить состояние формы, а работу по сохранения/чтения его в файл отдадим на откуп встроенному в java XML сериализатору.
И так создаем новый класс
фиксируем в него поля
теперь идем в Controller и в методе закрытия формы прописываем:
а теперь добавляем сериализацию в файл. Тут все просто
теперь проверяем как работает
Так-так, файлик появился. У меня внутри такие строчки:
теперь попробуем добавить чтение из файла. Чтение стало быть делаем в инициализаторе:
В этой главе мы подробно обсудим структуру приложения JavaFX, а также научимся создавать приложение JavaFX на примере.
Структура приложения JavaFX
В общем случае приложение JavaFX будет иметь три основных компонента, а именно Stage, Scene и Nodes, как показано на следующей диаграмме.
стадия
Этап (окно) содержит все объекты приложения JavaFX. Он представлен классом Stage пакета javafx.stage . Первичная стадия создается самой платформой. Созданный объект stage передается в качестве аргумента методу start () класса Application (объяснение в следующем разделе).
Этап имеет два параметра, определяющих его положение, а именно: ширина и высота . Он делится на область содержимого и украшения (строка заголовка и границы).
- Украшен
- неукрашенный
- прозрачный
- унифицированный
- Полезность
Вы должны вызвать метод show () для отображения содержимого сцены.
Сцена
Сцена представляет физическое содержимое приложения JavaFX. Он содержит все содержимое графа сцены. Класс Scene пакета javafx.scene представляет объект сцены. В случае, объект сцены добавляется только к одной сцене.
Вы можете создать сцену, создав экземпляр класса сцены. Вы можете выбрать размер сцены, передав ее размеры (высоту и ширину) вместе с корневым узлом ее конструктору.
Граф сцены и узлы
Контейнеры (панели макетов), такие как пограничная панель, сетка, потоковая панель и т. Д.
Медиа-элементы, такие как аудио, видео и изображения объектов.
Контейнеры (панели макетов), такие как пограничная панель, сетка, потоковая панель и т. Д.
Медиа-элементы, такие как аудио, видео и изображения объектов.
Класс Node пакета javafx.scene представляет узел в JavaFX, этот класс является суперклассом всех узлов.
Корневой узел . Первый граф сцены называется корневым узлом.
Узел ветвления / родительский узел . Узел с дочерними узлами называется узлами ветвления / родительского узла. Абстрактный класс с именем Parent пакета javafx.scene является базовым классом всех родительских узлов, и эти родительские узлы будут следующих типов:
Корневой узел . Первый граф сцены называется корневым узлом.
Узел ветвления / родительский узел . Узел с дочерними узлами называется узлами ветвления / родительского узла. Абстрактный класс с именем Parent пакета javafx.scene является базовым классом всех родительских узлов, и эти родительские узлы будут следующих типов:
Обязательно передать корневой узел графу сцены. Если группа передается как root, все узлы будут обрезаны до сцены, и любое изменение размера сцены не повлияет на макет сцены.
Создание приложения JavaFX
Чтобы создать приложение JavaFX, вам нужно создать экземпляр класса Application и реализовать его абстрактный метод start () . В этом методе мы напишем код для приложения JavaFX.
Класс приложения
Класс Application пакета javafx.application является точкой входа приложения в JavaFX. Чтобы создать приложение JavaFX, вам нужно унаследовать этот класс и реализовать его абстрактный метод start () . В этом методе вам нужно написать весь код для графики JavaFX
В основном методе вы должны запустить приложение, используя метод launch () . Этот метод внутренне вызывает метод start () класса Application, как показано в следующей программе.
В методе start () для создания типичного приложения JavaFX необходимо выполнить шаги, приведенные ниже:
Подготовьте граф сцены с необходимыми узлами.
Подготовьте сцену с необходимыми размерами и добавьте к ней граф сцены (корневой узел графа сцены).
Подготовьте сцену и добавьте сцену к сцене и отобразите содержимое сцены.
Подготовьте граф сцены с необходимыми узлами.
Подготовьте сцену с необходимыми размерами и добавьте к ней граф сцены (корневой узел графа сцены).
Подготовьте сцену и добавьте сцену к сцене и отобразите содержимое сцены.
Подготовка графа сцены
Согласно вашему приложению, вам нужно подготовить граф сцены с необходимыми узлами. Поскольку корневой узел является первым узлом, вам необходимо создать корневой узел. В качестве корневого узла вы можете выбрать из группы, региона или WebView .
Метод getChildren () класса Group предоставляет вам объект класса ObservableList, который содержит узлы. Мы можем извлечь этот объект и добавить к нему узлы, как показано ниже.
Мы также можем добавить объекты Node в группу, просто передав их классу Group и его конструктору во время создания экземпляра, как показано ниже.
Вы можете использовать эти классы для встраивания диаграмм в ваше приложение.
Вы можете использовать эти классы для вставки предопределенных макетов в ваше приложение.
Вы можете использовать эти классы для вставки различных элементов пользовательского интерфейса в ваше приложение.
Вы можете использовать эти классы для встраивания диаграмм в ваше приложение.
Вы можете использовать эти классы для вставки предопределенных макетов в ваше приложение.
Вы можете использовать эти классы для вставки различных элементов пользовательского интерфейса в ваше приложение.
В группе вы можете создать экземпляр любого из вышеупомянутых классов и использовать их в качестве корневых узлов, как показано в следующей программе.
Читайте также: