Enums in Model Classes
One application of enum types is to represent categories of objects. We will take this approach in our coding-events
application to categorize events based on their type, such as conference or meetup.
Enum Types in Models - Video
The starter code for this video is found at the display-errors branch
of the CodingEventsJava
repo.
The final code presented in this video is found on the enums branch
. As always, code along to the videos on your own codingevents
project.
As mentioned in the previous chapter
, your
display-errors
constructor might contain a small quirk. If your
constructor assigns non-sequential id
values, this is still OK!
Enum Types in Models - Text
Create an Enum Class
In your models
package within codingevents
, create a new class called EventType
.
Before you finish entering the name of your file, select the Enum
option from the list of
types.
Because enum values are constants, we use naming-conventions and write them in all caps. Each value is demarcated with a comma and the list is completed with a semicolon.
EventType
:
|
|
Add an Enum Field
Enums can store additional information affiliated with each value in fields. Enum fields
are treated like fields on any other type. Again, because enum values are constants, fields
should be final
variables, since they will not change.
To add a displayName
field to EventType
, we declare the field, add a constructor, and
tack on a getter method:
|
|
To define the display name for each of the EventType
values, we can call the constructor we
just wrote like this:
|
|
Add an Enum Property to a Model Class
Other objects can have enum type properties. To add an EventType
property to our model Event
,
we create a type
field in Event
amongst the other fields declared:
// other Event field declarations
private EventType type;
// Event methods
We’ll want to also add this field to the Event
constructor, as well as a getter and setter
method:
|
|
Pass Enum Values Through the Controller
codingevents
uses model binding to create an Event
object. So like any other field on
the model, the controller does not necessarily need to know about the addition of Event.type
in order to create an Event
instance from a form. However, we want the user to choose from
the pre-defined event type values when creating their event. To do this, we’ll use the
controller method displayCreateEventForm
to pass those values into the view.
In EventController
:
|
|
.values()
is a built-in static method that returns an array of values defined in
the given enum, in the order in which they have been declared.
With the template variable types
now defined, we can use our EventType
values in the view.
Use Enum Value in a Select
Element
The list of constants returned from EventType
lends itself well to a select
-type form
input. We’ll update our form so that a user will have the option to choose one of the provided
event types from a dropdown menu.
In templates/events/create.html
:
|
|
As with the other form inputs on the page, the th:field
attribute determines the name
and id
attributes for the select
tag. We make an option
tag for each of the EventType
values, making use of the types
variable we passed in from the controller in the previous step
. We set the value
attribute for the
model data to be the EventType
value using th:value
. And the type name shown to the user
of the form as the displayName
of the type, using th:text
.
Use Enum Properties to Display Information
Once an event is created, to display its type
field in the table of all events, we’ll modify
templates/events/index.html
to include another column:
<!-- other table headers -->
<th>Type</th>
<!-- other event data -->
<td th:text="${event.type.displayName}"</td>
In this case, the type displayed is the value of the event object’s type
field, so the controller
method responsible for rendering this view does not need a types
variable passed in. To show the
more user-friendly view of the type value, we use the .displayName
field of EventType
.
Check Your Understanding
When we add a field to the EventType
enum from codingevents
, what is the strongest
reason why we don’t we write a setter method for that field?
- Enum classes cannot contain setter methods
- Final variables cannot be reassigned
- Enum fields cannot be reassigned
- We don’t use a setter method in the rest of the application
In coding-events
, say we change our template variable name in
EventController.displayCreateEventForm
so that EventType.values()
is now assigned to
a variable, categories
. Which of the template expressions in the following code block
from create.html
, if any, should be changed to reflect this update? Select all that apply.
|
|
- In line 3,
${event.type}
should be changed to${event.category}
- In line 4,
type : ${types}
should be changed tocategory : ${categories}
- In line 5,
${type}
should be changed to${category}
- In line 6,
${type.displayName}
should be changed to${category.displayName}