Создание простого приложения JavaFX и JavaFX FXML. — КиберПедия 

Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...

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

Создание простого приложения JavaFX и JavaFX FXML.

2022-10-10 53
Создание простого приложения JavaFX и JavaFX FXML. 0.00 из 5.00 0 оценок
Заказать работу

Ну напишем первую программку на JavaFX.Выбираем «JavaFX»->«JavaFX»->«Приложение JavaFX»

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

Кстати, в сгенерированном коде нет никакой заглушки. Это просто стартовый проект. Хотите, все сотрите и пишите сами. Итак, от кого наследует наш класс? Кто такой Application? Это не относится к окну приложения ни в коем случае. Современная архитектура построена абсолютно иначе. Это движок приложения. У вас должен быть кто-то кто связывается с ОС, кто-то кто наше дерево загрузит и это будет run-timeработать. Это движок. Поэтому в архитектуре мы обязаны этот движок использовать, в данном случае просто от него наследуя. Мы обязаны переопределить всего один метод «@Override», а остальные по желанию, который называется start. Зачем? А кто даст дерево, которое должно потом сформировать пользовательский интерфейс? Кто? Вот startи даст.

Вопрос: Кто вызывает start?

Смотрим на main. Мы говорим: «давай! запускай свое приложение!». Кстати, main является частью этого нашего класса, естественно. И статический метод launch является методом хранящимся в Application, который позволяет этот движок поднять и запустить.

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

Applicationв лице launchсоздает объект JavaFX1. Он пинает метод start(). Он же полиморфный, он на объекте вызывается, и вот тут мы должны создать свой пользовательский интерфейс. А контейнер, в который вам все это положить, вам дают, чтобы вам не напрягаться. Почему? С ОС нужно взаимодействовать. Вот контейнер на слайде – javafx.stage

В этот stageвставляется сцена. А уже в сцену дерево объектов.

· Stage

o Сцена

§ И в него вставляется дерево объектов.

Итак, идем далее. Что в Stage должно класться? Вот смотрите. У нас есть последняя строчка. В Stageкладется сцена. В сцену кладется root. А в rootзакладывается пользовательский интерфейс.

Вопрос: Кстати, что у нас вообще на экране?

Ответ: Вау! Кнопка! Одна штука.

Вот у нас получается Stage, у нас в нем сцена, в ней вставлен root, а в rootдерево объектов. И у нас в дереве всего одна кнопка.

Вопрос: Работает?

Ответ: Работает.

Теперь делаем так. Закомментируем main.

Запускаем F6.

Работает.

Ну мы, конечно, не будет так жестко делать - убирать main. Но по крайней мере, почему когда мы не вызываем launch() и все работает? Он является уже частью программы, которая генерируется для JavaFX.

Дальше показываю. Находим наш проект в системе. Вот он *.jar-архив. Его нужно принести клиенту. Вы приносите клиенты и говорите: «вот я тебе jarархив принес». Как jar-архив запускается? cmd ->jarимя… Так вот в этом jarуже лежит launch. Люди понимают, что пользователи умеют делать двойной клик и в общем-то и всё. Ну конечно мы можем написать bat-файл. Положить на рабочий стол. По нему кликнуть. batподнимет там все что хочешь. Ну это же надо делать. А здесь пожалуйста, принес jar-архив, человек кликнул, программа запустилась и люди счастливы наконец-то.

Кстати, там есть интересные вещи, что когда собирается программа jarв JavaFX, там есть такая позиция (где-то галочку можно поставить). Она называется self-containedarchive. Туда даже JREположен. Т.е. вы сделаете один файлик. Принесете клиенту. Он его у себя кликнет, он развернется и там будет все, что нужно и будет запускаться.

Идем далее. Что у нас есть еще? Давайте глянем на «обработчик на события». Кстати, может быть сделаем вторую кнопку? Что это означает «сделать вторую кнопку»? Нужно еще раз написать «создать объект Button». Кстати, никаких имен! Нормальный Button, а не JButton,потому что здесь нет AWT. Видите? И свои eventsи своё всё. Это полностью самостоятельная библиотека. Понятно, что она может использовать JDK, но здесь все свое.

Итак. Если я хочу еще раз создать свой Button, ну вот пожалуйста. Вот у меня root, а вот у меня у меня добавляется кнопка.

1. Я говорю: «А я хочу еще кнопку!». Пожалуйста, вот тебе btn2. Сделали.

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

3. Созданный новый объект я должен добавить в root.

Нажимаем F6. Радуемся. Вот одна кнопка, вот другая кнопка.

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

Идем дальше. Обработка на события. Правило «JavaBeans» забудьте. Здесь все своё. Видите? Нету add, Listener. Поэтому они сказали: «хватит! делаем все с нуля». Метод, который позволяет оформить подписчика на событие, видите вызывается метод setOn….

И если я поставлю btn., то я увижу подписку на все, какие есть события.

Итак. Вот у меня создается здесь объект класс, и тут же его реализация. Метод handle, который отвечает, в этом интерфейсе должен быть реализован.

Кстати, вот эту писанину, которую вы здесь сейчас видите, вообще выглядит по-деревенски. А если написать не по-деревенски? Ничего, если я исправлю на вариант не деревенский?

Готовы? Лямбда-выражение надо написать.

Я специально не проверял, но по-моему у них нет такого, чтобы в интерфейсе было 7 методов, как в AWT.

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

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

Задача: Давайте мы эти две кнопки делаем отдельно в конце концов. Я иногда пытался сделать интерфейс, как на следующем слайде.

Ну тут слишком наворочено. Как минимум 6 элементов управления придется создавать – 3 надписи и 3 текстовых поля. Но свойства-то нет. Разницы нет. Что я создам 2 элемента, что 6. Суть от этого сильно не изменится. Но давайте попробуем.

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

ПишемвместоStackPaneroot = newStackPane(); - GridPaneroot = newGridPane();

Не то! Где оказались оба элемента управления? В первой ячейке в первой строке. Видите? Они друг на друге опять же. Понятно. Когда мы добавляем в GridPaneчерез метод addи добавляем без указания «куда?», то оно попадает в первую ячейку. Поэтому эти две строчки я сейчас закомментирую и мы должны поместить уже в конкретный элемент. Давайте попробуем. У нас есть root, который теперь стал Grid, а значит у него должен появиться новый функционал. У него кстати есть свой собственный вариант add, где вторым параметром идет столбец, а третьим – строчка. Допустим я говорю: «Добавь мне Button»в нулевой столбец, в нулевую строчку. А дальше можно было бы написать, сколько объединяется столбцов и строчек. Тогда следующий элемент у меня будет ниже. Соответственно, я беру свой Gridи добавляю btn2. – у меня будет уже нулевой столбец и первая строчка.

Ну собственного говоря Gridон и должен всегда одинаково выглядеть практически, как и во всех библиотеках.

Наверно надо бы добавить еще по паре элементов. А пусть будут те же самые кнопки.

Видите, да? Т.е. у нас ячейки в Gridопределяются элементами. Элементы занимают всю ячейку. Ну а соответственно ниже по столбцу идет размер ячейки по максимальному номеру. Ну в целом разумно. Единственно, что мы вот здесь не сделали, а могли бы – это как на этом слайде.

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

Но что мне здесь принципиально не нравится в этой программе? Посмотрите на нее. Ну что это такое? Это прошлый век. Код и тут же обработчики. Ну в Swingтакже было? Да. Здесь так же? Да. Если взять WinApiна котором мы писали в прошлом веке, также? Да. Это архитектура. Это одна из возможностей как мы пишем программы. Но с т.з. модификации и улучшения не выдерживает никакой критики. Но слава Богу мы не должны здесь искать решения, потому что авторы-разработчики уже все сделали. Они сказали: «Смотрите! У нас есть альтернатива! Да, вы можете делать все в коде, но вы можете пользовательский интерфейс вынести в отдельный файл». И он называется «FXML».

Ну *.xml – специальная разметка. Учтите, что этот FXML-файл парсится. Каждый элемент, который будет в нем найден – будет создан соответствующий объект. В XML элементы вложены друг в друга? Да. Значит мы получим дерево – родитель, внутренний объект, дочерний и т.д. Поэтому FXMLсоздает вам сразу правильное дерево и когда он парсится, вы получаете дерево объектов. И именно это дерево объектов и будет в run-timeсуществовать и это дерево объектов будет рендериться и отображаться. И именно графическая утилита SceneBuilderона и должна генерировать именно этот XML-файл, потому что как две совершенно разные среды между собой совместить? Дизайнерская среда не должна генерировать Java-код. Если дизайнер не дай Бог откроет код, что он там поймет? А FXML, разметку, каскадные стили – кто-то с этим должен разбираться. Поэтому нам предлагают абсолютно альтернативный вариант, как вы можете начинать делать приложения. Ну так давайте попробуем! Если есть альтернатива, надо пробовать.

Создаем проект JavaFX2

Выбираем «Приложение FXMLJavaFX»и нажимаем «Готово».

Если посмотреть на проект, то у нас 3 файла в package!

Все разбито на три части. Функционал примерно такой же. Я сразу запущу программу, чтобы вы увидели, что программа стала ненамного сложнее, ненамного объемнее.

И если вы на нее нажмете, то тут чуть-чуть иначе сделана обработка события. У нас оказывается есть еще второй элемент в пользовательском интерфейсе. Мы его не видели, потому что он пустой. Когда вы нажмете на кнопку, она на всякий случай бросила вам сообщение «окошко-вывод», а еще элемент управления. Т.е. их там два.

Давайте теперь посмотрим на код.

Если все importпропустить, то у нас идет наследование. Я не буду сейчас уничтожать main – она мне в принципе не мешает. Но если ее от сюда выкинуть, то получается, что в startу вас 4 строчки кода. В общем-то больше и не надо, потому что в s tage кладут scene. А в sceneкладут root. А rootберется обратите внимание из одной строчки.И эта строчка говорит: «загрузи FXML-документ.fxml»

Т.е. у нас есть пользовательский интерфейс в fxml-файле.

Давайте откроем его – это же часть проекта.

Вот он FXML.Пожалуйста! Вот он! Классический вариант создания современных интерфейсов с помощью FXML-файла. Корневой объект вы видите – «AnchorPane». Учтите, что это не просто имя тега, а имя класса. Именно объект этого типа и будет создан. А вот его коллекция дочерних элементов. Помните в коде было «root.getChildren()»? Вот он children. А внутри children – кнопочка и label. Значит будут созданы в дереве кнопочка и label. Имена здесь соответствуют классам JavaFX. Собственно говоря, парсер так и будет понимать, какой объект нужно взять.


Поделиться с друзьями:

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

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...

Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...

Особенности сооружения опор в сложных условиях: Сооружение ВЛ в районах с суровыми климатическими и тяжелыми геологическими условиями...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.051 с.