This review aims to introduce functional interface applied to a concrete application : creating menu with graphical API Swing.


Application controller


For this review purpose, we will consider a simple application that offers a traditional File menu, with three actions : Open, Save and Exit.

With Swing, each menu item should be connected to the functional interface ActionListener, in order to perform an associated action. Since method reference could be now interpreted as functional interface, we will consider the Controller interface which provides a functional method for each action it could handle.





To build our menu, we will first setup a dedicated class for building a JMenu entry, named MenuBuilder. The following snippet shows our class header. We also made our class implements Supplier interface as it aims to provide a JMenu.



Now in order to fill our menu, we will add a method for creating a menu item instance using a given label, and ActionListener, which will be added to the target JMenu :




Finally, we need to setup a component which will be in charge of creating a JMenuBar, and will only contains the two following atttributes :




You can notice that the constructor is set as private, only a static factory method would be provided later.


Then creating a menu will be as simple as following, we only have to use the previously defined MenuBuilder class, with method reference from our Controller instance as ActionListener for creating menu entry :



Last step, we have to define a static factory method for using our class which will prevent from misusage. Here we only have one menu, but you could add method as much as menu you have.



Bonus : Item delayed activation


Our menu is working, but let’s improve it. Imagine you want to set the Save item disabled until a file has been opened. To do so, we will use the method you probably have noticed while looking the UML class diagram for the MenuBuilder : createActivable(String, ActionListener).

This method creates a JMenuItem by calling the createItem(String, ActionListener) method, and then returns a Runnable object :



As you can see, the returned Runnable instance is only enabling the associated menu item, and could then be used in order to activate the entry. To integrate this behavior for the Save item, we will update our Controller interface, and make it extends Consumer for Runnable type :



And use the associated accept(Runnable) method into the file menu creation :



The Controller implementation will just have to store the given Runnable and call it during the open(ActionEvent) method.


Download


Controller.java
MenuBuilder.java
MenuBarBuilder.java