Javarevisited
Published in

Javarevisited

Experimenting with Java enums, emojis, and ComboBox in JavaFX

Learn how to use Java enums and emojis with a JavaFX ComboBox.

ToDoCategory Java enum with emojis

Upgrading my JavaFX ToDoList application

In the second iteration of my Java TodoListApplication, I used the JavaFX DatePicker and TableView components. I also introduced a Java record named ToDoItem to see how I could use records in a JavaFX application.

I said in my previous blog that I was going to make my ToDoList persistent. I’m still planning on doing this (next blog!), but I realized I wanted to add one more piece of information first to my ToDoItem before making it persistent.

Adding a ToDoCategory enum

I wanted to add a category to my ToDoItem record to keep track of to do items by category. So I created a ToDoCategory enum with categories that match things that I do on a regular basis.

public enum ToDoCategory
{
EXERCISE("🚴"),
WORK("πŸ“Š"),
RELAX("🧘"),
TV("πŸ“Ί"),
READ("πŸ“š"),
EVENT("🎭"),
CODE("πŸ’»"),
COFFEE("β˜•οΈ"),
EAT("🍽"),
SHOP("πŸ›’"),
SLEEP("😴");

private String emoji;

ToDoCategory(String emoji)
{
this.emoji = emoji;
}

public String getEmoji()
{
return this.emoji;
}
}

I added a getter for the emoji String named getEmoji. This will be important later.

Updating my ToDoItem record

It was a fairly straightforward change to update my ToDoItem record with the ToDoCategory. The important bit is that while the ToDoItem holds onto a reference to a ToDoCategory, it will return the emoji from the category in the getCategory method.

public record ToDoItem(String name, ToDoCategory category, LocalDate date)
{
public String getCategory()
{
return this.category.getEmoji();
}

public String getName()
{
return this.name;
}

public String getDate()
{
return this.date.toString();
}
}

Adding a ComboBox

The next step I wanted to add a ComboBox to my todolist-view.fxml. I placed the todoCategory ComboBox between the todoItem TextField and todoDate DatePicker.

<HBox id="HBox1" alignment="CENTER_LEFT" spacing="5.0">
<Label text="Item: " />
<TextField fx:id="todoItem" />
<Label text="Category: " />
<ComboBox fx:id="todoCategory" />
<Label text="Date: " />
<DatePicker fx:id="todoDate" />
</HBox>

I bound the ComboBox to a variable named todoCategory and added it to my TodoListController.

@FXML
public ComboBox<ToDoCategory> todoCategory;

Then I needed to write some code to populate the values in the ComboxBox with all of the ToDoCategory enum values. So I updated the initialize method of the TodoListController.

@FXML
protected void initialize()
{
this.todoList.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
MutableList<ToDoItem> items = Lists.mutable.empty();
ObservableList<ToDoItem> list = FXCollections.observableList(items);
this.todoList.setItems(list);
ObservableList<ToDoCategory> categories =
FXCollections.observableList(Lists.mutable.with(ToDoCategory.values()));
this.todoCategory.setItems(categories);
}

I wrapped the array returned from the values method of the ToDoCategory enum with an Eclipse Collections MutableList, and then wrapped that in an ObservableList using the FXCollections utility class.

The text that is displayed in the ComboBox is the return value for the toString implementation for each of the enums, which will be the enum text itself. This works as I had hoped.

Updating the onAddButtonClick code

When the add button is clicked, I now need to construct the ToDoItem instance with all three UI component values. This was straightforward to add the todoCategory ComboBox selected value.

@FXML
protected void onAddButtonClick()
{
ToDoItem item = new ToDoItem(
this.todoItem.getText(),
this.todoCategory.getValue(),
this.todoDate.getValue());

this.todoList.getItems().add(item);
}

Adding a category column to the TableView

Finally, I wanted to add the category column to the TableView. I decided it would be cool to display the emoji value for the ToDoCategory enum here.

<TableView fx:id="todoList">
<columns>
<TableColumn text="Name" minWidth="75.0" sortable="true">
<cellValueFactory>
<PropertyValueFactory property="name" />
</cellValueFactory>
</TableColumn>
<TableColumn text="Category" minWidth="50.0" sortable="true">
<cellValueFactory>
<PropertyValueFactory property="category" />
</cellValueFactory>
</TableColumn>
<TableColumn text="Date" minWidth="50.0" sortable="true">
<cellValueFactory>
<PropertyValueFactory property="date" />
</cellValueFactory>
</TableColumn>
</columns>
</TableView>

I added the category column between the name and date columns and made it sortable.

My updated JavaFX TodoListApplication View

This is what my TodoListApplication looks like running now.

You may note that I have a category for reading, but not for writing. I may change this, but decided for this iteration, I would just categorize writing this blog under RELAX. Writing is a form of mental relaxation for me. I keep very focused, sort my thoughts, and write them down relieving my brain of having to hold onto too much information. Writing is my mental equivalent of Yoga.

My todolist-view.fxml & TodoListController Source

Out of convenience, I have put most of my code including the ToDoItem and ToDoCategory types in the TodoController class. I may change this in future iterations. The TodoListApplicaton code hasn’t changed since my last blog, so please refer to it there if you want.

todolist-view.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.control.ComboBox?>
<?import javafx.scene.control.DatePicker?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<VBox alignment="CENTER" spacing="20.0" xmlns:fx="http://javafx.com/fxml"
fx:controller="example.todolist.TodoListController">
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>

<HBox id="HBox1" alignment="CENTER_LEFT" spacing="5.0">
<Label text="Item: " />
<TextField fx:id="todoItem" />
<Label text="Category: " />
<ComboBox fx:id="todoCategory" />
<Label text="Date: " />
<DatePicker fx:id="todoDate" />
</HBox>
<TableView fx:id="todoList">
<columns>
<TableColumn text="Name" minWidth="75.0" sortable="true">
<cellValueFactory>
<PropertyValueFactory property="name" />
</cellValueFactory>
</TableColumn>
<TableColumn text="Category" minWidth="50.0" sortable="true">
<cellValueFactory>
<PropertyValueFactory property="category" />
</cellValueFactory>
</TableColumn>
<TableColumn text="Date" minWidth="50.0" sortable="true">
<cellValueFactory>
<PropertyValueFactory property="date" />
</cellValueFactory>
</TableColumn>
</columns>
</TableView>
<HBox id="HBox2" alignment="CENTER" spacing="5.0">
<Button text="Add" onAction="#onAddButtonClick" alignment="BOTTOM_LEFT" />
<Button text="Remove" onAction="#onRemoveButtonClick" alignment="BOTTOM_RIGHT" />
</HBox>
</VBox>

TodoListController

package example.todolist;

import java.time.LocalDate;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.ComboBox;
import javafx.scene.control.DatePicker;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import org.eclipse.collections.api.factory.Lists;
import org.eclipse.collections.api.list.MutableList;

public class TodoListController
{
@FXML
private TextField todoItem;

@FXML
public ComboBox<ToDoCategory> todoCategory;

@FXML
private DatePicker todoDate;

@FXML
private TableView<ToDoItem> todoList;

@FXML
protected void initialize()
{
this.todoList.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
MutableList<ToDoItem> items = Lists.mutable.empty();
ObservableList<ToDoItem> list = FXCollections.observableList(items);
this.todoList.setItems(list);
ObservableList<ToDoCategory> categories =
FXCollections.observableList(
Lists.mutable.with(ToDoCategory.values()));
this.todoCategory.setItems(categories);
}

@FXML
protected void onAddButtonClick()
{
ToDoItem item = new ToDoItem(
this.todoItem.getText(),
this.todoCategory.getValue(),
this.todoDate.getValue());

this.todoList.getItems().add(item);
}

@FXML
protected void onRemoveButtonClick()
{
int indexToRemove = this.todoList.getSelectionModel()
.getSelectedIndex();
this.todoList.getItems().remove(indexToRemove);
}

public record ToDoItem(String name, ToDoCategory category, LocalDate date)
{
public String getCategory()
{
return this.category.getEmoji();
}

public String getName()
{
return this.name;
}

public String getDate()
{
return this.date.toString();
}
}

public enum ToDoCategory
{
EXERCISE("🚴"),
WORK("πŸ“Š"),
RELAX("🧘"),
TV("πŸ“Ί"),
READ("πŸ“š"),
EVENT("🎭"),
CODE("πŸ’»"),
COFFEE("β˜•οΈ"),
EAT("🍽"),
SHOP("πŸ›’"),
SLEEP("😴");

private String emoji;

ToDoCategory(String emoji)
{
this.emoji = emoji;
}

public String getEmoji()
{
return this.emoji;
}
}
}

Next Steps

My next step will be to make my ToDo List persistent. I’ve used enough JavaFX components now and want to experience more of the lifecycle of a JavaFX application. I hope you enjoyed this brief detour of using Java enum, emojis and ComboBox in JavaFX. πŸ˜€

Thank you for reading!

I am the creator of and a Committer for the Eclipse Collections OSS project which is managed at the Eclipse Foundation. Eclipse Collections is open for contributions.

--

--

A humble place to learn Java and Programming better.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Donald Raab

Java Champion. Creator of the Eclipse Collections OSS Java library (http://www.eclipse.org/collections/). Inspired by Smalltalk. Opinions are my own.