Occasionally when working with JSF I have the need to display the values of a Java Enum in a pick-list.
public enum Cars {
KIA,
BMW,
TOYOTA,
FERRARI
}
Returning an array of these values is easy enough. Cars.values();
The ordering of the values in the array is set by the ordinal value of the enum, or more simply the order which it appears in the source code. {"KIA", "BMW", "TOYOTA", FERRARI"}
Now depending on your application, if you need to change the order you can simply change the order they appear in the source code. However if you are like me and persisting these values to a database based on their ordinal value to save space then changing the order will break your application.
@NotNull
@Column(columnDefinition = "tinyint")
@Enumerated(EnumType.ORDINAL)
public Cars getCar() {
return car;
}
public void setEgressCodec(Cars car) {
this.car = car;
}
The first thing you might want to do is implement Comparable on the Enum and override the compareTo with your own to control the ordering. Unfortunately compareTo() is final on the Enum so we can’t override it.
Here is the solution that I’ve come up with.
First I create a new interface called ComparableEnum
ComparableEnum.java
public interface ComparableEnum {
public String getDisplayName();
public int getPriority();
public boolean isDisplayed();
public int ordinal();
}
Then I can implement this on my Cars Enum using the cost a car as a value for the priority
Cars.java
public enum Cars implements ComparableEnum {
KIA("Kia Motors", 15000, true),
BMW("Bavarian Motor Works", 55000, true),
TOYOTA("Toyota Motors", 35000, true),
FERRARI("Ferrari S.p.A.", 150000, true)
private String displayName;
private int priority;
private boolean displayed;
private Cars(String displayName, int priority, boolean displayed) {
this.displayName = displayName;
this.priority = priority;
this.displayed = displayed;
}
public String getDisplayName() {
return displayName;
}
public int getPriority() {
return priority;
}
public boolean isDisplayed() {
return displayed;
}
}
Now it’s just a matter adding a couple comparators
EnumNameComparator.java
public class EnumNameComparator<T extends ComparableEnum> implements Comparator<T> {
public int compare(T o1, T o2)
{
if (o1.getDisplayName().compareTo(o2.getDisplayName()) != 0){
return o1.getDisplayName().compareTo(o2.getDisplayName());
}
else if (o1.toString().compareTo(o2.toString()) != 0) {
return o1.toString().compareTo(o2.toString());
}
else {
return new Integer(o1.ordinal()).compareTo(new Integer(o2.ordinal()));
}
}
}
EnumPriorityComparator.java
public class EnumPriorityComparator<T extends ComparableEnum> implements Comparator<T> {
public int compare(T o1, T o2)
{
if (new Integer(o1.getPriority()).compareTo(new Integer(o2.getPriority())) != 0)
{
return new Integer(o1.getPriority()).compareTo(new Integer(o2.getPriority()));
}
else if (o1.toString().compareTo(o2.toString()) != 0)
{
return o1.toString().compareTo(o2.toString());
}
else
{
return new Integer(o1.ordinal()).compareTo(new Integer(o2.ordinal()));
}
}
}
Now I want to be able to sort these easily using any enum I have which implements Comparable enum so I add a generic method.
private static <T extends ComparableEnum> List<T> getEnumSortedByPriority(T[] t) {
EnumPriorityComparator<T> c = new EnumPriorityComparator<T>();
List<T> list = removeNonDispalyedValues(t);
Collections.sort(list, c);
return list;
}
Now I can create a simple method to return my enum sorted how I wish
public static List<Cars> componentTypes() {
return getEnumSortedByPriority(ComponentType.values());
}