Как заполнить combobox javafx
Перейти к содержимому

Как заполнить combobox javafx

Как заполнить combobox javafx

Класс javafx.scene.control.ComboBox<T> позволяет создать выпадающий список. Данный класс типизируется типом элементов, которые будут храниться в списке.

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

    ComboBox() : создает пустой выпадающий список

Из методов ComboBox следуюет выделить следующие:

void setValue(T item) : устанавливает выбранный по умолчанию элемент (если не вызвать данный метод, то по умолчанию никакой элемент не будет выбран)

T item getValue() : возвращает текущий выбранный элемент

void setOnAction​(EventHandler<ActionEvent> value) : устанавливает обработчик, который срабатывает при выборе элемента в списке

Release: JavaFX 2.2

The picture of the authorAlla is a technical writer for Oracle. She lives in St. Petersburg, Russia, and develops tutorials and technical articles for Java and JavaFX technologies. Prior to her assignment at Oracle, she worked as a technical writer in different IT companies.

We Welcome Your Comments

If you have questions about JavaFX, please go to the forum.

Using JavaFX UI Controls

14 Combo Box

This chapter explains how to use combo boxes in your JavaFX application. It discusses editable and uneditable combo boxes, teaches you how to track changes in the editable combo boxes and handle events on them, and explains how to use cell factories to alter the default implementation of a combo box.

A combo box is a typical element of a user interface that enables users to choose one of several options. A combo box is helpful when the number of items to show exceeds some limit, because it can add scrolling to the drop down list, unlike a choice box. If the number of items does not exceed a certain limit, developers can decide whether a combo box or a choice box better suits their needs.

You can create a combo box in the JavaFX application by using the ComboBox class of the JavaFX API. Figure 14-1 shows an application with two combo boxes.

Figure 14-1 Application with Two Combo Boxes

Description of Figure 14-1 follows
Description of «Figure 14-1 Application with Two Combo Boxes»

Creating Combo Boxes

When creating a combo box, you must instantiate the ComboBox class and define the items as an observable list, just like other UI controls such as ChoiceBox , ListView , and TableView . Example 14-1 sets the items within a constructor.

Example 14-1 Creating a Combo Box with an Observable List

Another possibility is to create a combo box by using an empty constructor and call the setItems method on it, as follows: comboBox.setItems(options);

When the combo box is added to the application scene, it appears in the user interface as shown in Figure 14-2.

Figure 14-2 Combo Box with Three Items

Description of Figure 14-2 follows
Description of «Figure 14-2 Combo Box with Three Items»

At any time, you can supplement the list of items with new values. Example 14-2 implements this task by adding three more items to the comboBox control.

Example 14-2 Adding Items to a Combo Box

The ComboBox class provides handy properties and methods to use with combo boxes.

You can use the setValue method to specify the item selected in the combo box. When you call the setValue method on the ComboBox object, the selected item of the selectionModel property changes to this value even if the value is not in the combo box items list. If the items list then changes to include this value, the corresponding item becomes selected.

Similarly, you can obtain the value of the selected item by calling the getValue method. When a user selects an item, the selected item of the selectionModel property and the combo box value property are both updated to the new value.

You can also restrict the number of visible rows in the ComboBox drop down list when it is displayed. The following code line enables the display of three items for the comboBox control: comboBox.setVisibleRowCount(3) As the result of calling this method, the number of visible rows is limited to three, and a scroll bar appears (as shown in Figure 14-3).

Figure 14-3 Setting the Number of Visible Rows for a Combo Box

Description of «Figure 14-3 Setting the Number of Visible Rows for a Combo Box»

Although the ComboBox class has a generic notation and enables users to populate it with items of various types, do not use Node (or any subclass) as the type. Because the scene graph concept implies that only one Node object can be in one place of the application scene, the selected item is removed from the ComboBox list of items. When the selection changes, the previously selected item returns to the list and the new selection is removed. To prevent this situation, use the cell factory mechanism and the solution described in the API documentation. The cell factory mechanism is particularly helpful when you need to change the initial behavior or appearance of the ComboBox object.

The ComboBoxSample application is designed to illustrate how to use combo boxes in a typical email interface. Example 14-3 creates a such an interface, in which two combo boxes are used to select the email recipient and the priority of the message.

Example 14-3 Creating Combo Boxes and Adding Them to the Scene

Both combo boxes in Example 14-3 use the getItems and addAll methods to add items. When you compile and run this code, it produces the application window shown in Figure 14-4.

Figure 14-4 Email Recipient and Priority Combo Boxes

Description of Figure 14-4 follows
Description of «Figure 14-4 Email Recipient and Priority Combo Boxes»

Editable Combo Boxes

Typically, email client applications enable users to both select recipients from the address book and type a new address. An editable combo box perfectly fits this task. Use the setEditable(true) method of the ComboBox class to make a combo box editable. With the setPromptText method, you can specify the text to appear in the combo box editing area when no selection is performed. Examine the modified code of the application in Example 14-4. The bold lines are the additions made to Example 14-3.

Example 14-4 Processing Newly Typed Values in an Editable Combo Box

Besides the ability to edit emailComboBox , this code fragment implements event handling for this control. The newly typed or selected value is stored in the address variable. When users press the Send button, the notification containing the email address is shown.

Figure 14-5 captures the moment when a user is editing the email address of Jacob Smith and changing it to greg.smith@example.com.

Figure 14-5 Editing an Email Address

Description of Figure 14-5 follows
Description of «Figure 14-5 Editing an Email Address»

When the Send button is pressed, all the controls return to their default states. The clear methods are called on the TextField and TextArea objects, and the null value is set for the combo box selected items. Figure 14-6 shows the moment after the Send button is pressed.

Figure 14-6 User Interface After the Send Button Is Pressed

Description of Figure 14-6 follows
Description of «Figure 14-6 User Interface After the Send Button Is Pressed»

Applying Cell Factories to Combo Boxes

You can use the cell factory mechanism to alter the default behavior or appearance of a combo box. Example 14-5 creates a cell factory and applies it to the priority combo box to highlight priority types with special colors.

Example 14-5 Implementing a Cell Factory for the Priority Combo Box

The cell factory produces ListCell objects. Every cell is associated with a single combo box item. The width of each combo box item is set through the setPrefWidth method. The updateItem method sets the red color for the High and Highest items, green color for the Low and Lowest items, and leaves the Normal item black.

Figure 14-7 shows the items of the priority combo box after the cell factory in Example 14-5 is applied.

Figure 14-7 Modified the Priority Combo Box

Description of Figure 14-7 follows
Description of «Figure 14-7 Modified the Priority Combo Box»

You can further enhance the appearance of the ComboBox control by applying CSS styles or visual effects.

Устанавливаем SceneBuilder

В отличие от Swing где можно править код прямо в среде. Для JavaFX надо установить отдельное приложение, чтобы можно было редактировать интерфейс в режиме WYSIWYG.

Для этого идем сюда https://gluonhq.com/products/scene-builder/#download и скачиваем версию под свою систему.

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

Imgur

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

Imgur

Imgur

Imgur

по завершению установки запустится SceneBuilder

Imgur

но он нам пока не нужен, так что можно его закрыть.

Создаем JavaFX приложение

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

Imgur

назову его CustomTypeGUI

Imgur

получаем такую структуру проекта:

Imgur

Принцип организации javafx интерфейса

Кликнем дважды на файлик sample.fxml чтобы открыть его и увидим там что-то такое:

fxml – это такой аналог html, только в рамках java, тут даже есть всякие импорты. И есть тэги, определяющие что будет отображаться. Тут к нас пока только один тэг GridPane, которые используется для выравнивания компонент по сетке.

Правда пока выравнивать нечего, так что пока это по сути пустой контейнер.

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

И так, попробуем запустить программу. Увидим что-то такое

Imgur

Откуда же это все взялось? А на самом деле ничего хитрого нет. Открываем файлик Main.java и видим

Добавляем кнопку

Вернемся к файлу sample.fxml. Теперь запустим SceneBuidler, выбираем Open Project

Imgur

и открываем наш файлик. Увидим что-то такое

Imgur

Перетянем теперь кнопку на форму. Так как пока у нас пустой GridPane наша форма выглядит как пустота. Но тянуть можно:

Сохраним перетянутое Ctrl+S и переключимся обратно в Idea. И глянем что у нас выросло с файлике sample.fxml. Там у нас будет такое:

Видим, что тут много чего поменялось. Появились какие-то Constraints (это так называем ограничения на размеры колонок и строк, нам они пока не интересны).

Ну и главное, что тут появился тег children и внутри него наша кнопочка

  • text – это то что написано на кнопке
  • mnemonicParsing – это специальный тег для обработки горячих клавиш, но нам это сейчас неинтересно, так что можно игнорировать

Можно попробовать запустить:

Imgur

ура, есть кнопочка! =)

Добавляем реакцию на нажатие

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

Переключимся на файл Controller.java:

Помните я упомянул атрибут fx:controller=”sample.Controller” внутри sample.fxml, так вот мы сейчас в том самом классе на который указывал этот атрибут. За счет него происходит связывание интерфейса и логики (контроллера).

Чтобы добавить реакцию на клик достаточно сделать следующие операции.

Сначала надо добавить функцию. Такую, например, пусть она просто выводит сообщение в консоль

Можно даже попробовать запустить. И потыкать кнопку

Imgur

хехе, очевидно ничего не произойдет. Мы ж пока функцию не привязали =)

А теперь переключимся на SceneBuilder и привяжем кнопку к функции

не забудем сохранить, и запустим проект по-новому

Кстати можно открыть файлик sample.fxml и глянуть что там произошло:

видите, появился атрибут onAction=»#showMessage» в котором указана функцию через решетку, которую надо вызвать при клике

Читаем значение из текстового поля

Ну тыкать на кнопочки и выполнять всякие функции — это конечно важное умение. Но не менее важно уметь считать значение из поля, например, текстового.

Делается это в некотором роде проще чем привязка кнопки.

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

Что я сделаю? Сначала создам в классе поле, через которое образуется связь

теперь переключимся на SceneBuilder, перетащим текстовое поле на форму, а затем привяжем его к нашему классу, путем указания свойства fx:id:

если вдруг у вас в этом поле ничего не высветилось, то можете смело вписать туда вручную txtInput.

Сохраним в SceneBuilder и вернемся обратно в Idea. Если глянуть в файлик fxml то увидим

Imgur

теперь вернемся в наш Controller и подправим метод showMessage:

Меняем значения текстового поля

О, давайте еще научимся изменять значение в списке, но тут все просто

В принципе вот и вся наука =)

  • добавил поле в контроллер
  • добавил объект в SceneBuilder
  • связал через fx:id, либо связал с методом.

Теперь можно пилить что-нибудь посложнее.

Ремарка

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

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

К тому же в JavaFX есть много хитрых особенностей, которые в WindowsForms не встречалось.

Добавление выпадающего списка (ComboBox)

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

теперь добавляем на форму

затем подключаем по fx:id

Imgur

не забываем сохраниться в SceneBuilder.

Запускаем и проверяем:

Imgur

Ура! Есть список! Правда пустой пока…

Заполняем список (интерфейс Initializable)

И вот незадача, как же его заполнить? У нас по сути голый класс Controller, без ничего. Давайте попробуем в конструкторе:

запускаем и… бдыщь

Imgur

суть стенаний виртуальной машины заключается в том, что comboBox нулевой. А нулевой он потому что привязка полей помеченных декоратором @FXML происходит уже после вызова конструктора, где-то в терньях фреймворка JavaFX.

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

Что ж делать? Оказывается все просто! Надо наследоваться от некого интерфейса Initializable и переопределить одну функцию, которую используется как своего конструктор формы. Делается это так

загоним теперь в метод initialize наш вызов добавления элемента

Imgur

Добавляем реакцию на переключения списка

Давайте сначала добавим еще несколько элементов

Есть как минимум два способа добавить реакцию на переключения

Через SceneBuilder

Imgur

не забываем сохраниться.

2) Затем в IDEA тыкаем правой кнопкой мыши на название метода

Imgur

выбираем первый пункт Show Context Actions, а затем:

Imgur

3) Нас перекинет в контроллер где мы увидим новодобавленный метод

в принципе, его можно было и руками добавить >_>

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

Через лямбда-функцию

Ну тут просто в методе инициализации привязываете лямбда-функцию к реакции на изменение свойства.

Я на лекции расскажу что тут происходит на самом деле

Работа с CheckBox

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

добавим в Controller:

теперь подключим checkbox к форме

ну теперь мы можем, например, управлять им кликая на кнопку:

ой, забыли кнопке указать другую функцию

Вот теперь красота! =)

кстати если хотите текст поменять то правьте поле Text:

Сохраняем состояние формы

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

Как правило для хранения состояния приложения используют простые файлы в каком-нибудь распространённом формате типа *.xml, *.ini, *.json

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

Подключаем обработчик закрытия формы

Мы будем сохранять в момент закрытия формы.

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

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

Там есть понятие stage (англ. состояние, сцена как место где происходят события), которое представляет собой окно приложения и scene (англ. тоже сцена, но уже в качестве события) которая, если немного упростить, представляет собой fxml файлик + контроллер.

Ну и ясно что именно к scene привязывается класс Controller. И так как scene за окно формы (то бишь stage) не отвечает, то из него и нельзя получить прямого доступа к событию закрытия окна.

Но можно получить не прямой. Для этого надо поймать событие закрытия формы (то бишь stage) и проксировать его в Controller. Делается это так:

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

теперь идем в Main и делаем магические пассы:

Сохраняем состояние формы в файл

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

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

И так создаем новый класс

Imgur

фиксируем в него поля

теперь идем в Controller и в методе закрытия формы прописываем:

а теперь добавляем сериализацию в файл. Тут все просто

теперь проверяем как работает

Так-так, файлик появился. У меня внутри такие строчки:

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *