Java Tips Weblog

  • Blog Stats

    • 2,530,124 hits
  • Categories

  • Archives

Swing and Java 8

Posted by Darryl Burke on April 5, 2015

Java 7 brought us JLayer (which I haven’t played with), Generics in JComboBox and JList, and a lonely collections-oriented JList#getSelectedValuesList().  Java 8, on the other hand, did not introduce any new Swing API.  However, enhanced language features can certainly make Swing code less verbose and more maintainable, and the new Date/Time API makes it easier than ever before to create interactive Swing components for date and/or time selection.

Chief among the new Java language features is the much-awaited lambda (or ƛ) expression, which can replace an anonymous inner class with just one line of code.  This is what traditional code to launch a Swing GUI looks like:

SwingUtilities.invokeLater(new Runnable() {

  public void run() {
    new SwingGui().createUI();
  }
});

Using a lambda expression reduces those 6 lines to:

SwingUtilities.invokeLater(() -> new SwingGui().createUI());

The same applies to listener code.  The design choice to implement listeners in the main GUI class, adopted by many, did allow for shorter code than anonymous inner classes, but also made the main classes prone to misuse.  With lambdas and their companion, method references, we have the best of both worlds: one line of code to add a listener that invokes a method in the GUI class, without the slightest need for that class to implement the listener interface.

myButton.addActionListener(ae -> buttonClickAction());
...
...
public void buttonClickAction() {
// react to button click
}

By providing a method that can accept an ActionEvent parameter, you can use a method reference instead.

myButton.addActionListener(this::buttonClickAction);
...
public void buttonClickAction(ActionEvent ae) {
// react to button click
}

Further, a lot of listener code ignores the passed-in event object; a single method will then suffice for different types of listeners.  All that is needed is that the listener be a functional interface, that is, it must have only one method to be implemented, and that the method referenced must be able to accept the parameter passed to the listener’s functional method.

myButton.addActionListener(this::listenerMethod);
mySpinner.addChangeListener(this::listenerMethod);
myList.addListSelectionListener(this::listenerMethod);
myTree.addTreeSelectionListener(this::listenerMethod);
...
public void listenerMethod(EventObject /* or Object */ ignored) {
// get values from components and process them
}

Going back to launching a Swing GUI, if the createUI() method is static, you can use a method reference there too:

SwingUtilities.invokeLater(SwingGui::createUI);

And if the GUI is created and set visible in a no-arg constructor, this will do it:

SwingUtilities.invokeLater(SwingGui::new);

If you are using Java 8, we hope that this brief introduction will help you reduce several lines of code and the attendant indentation associated with anonymous inner classes, making your program less cluttered and more maintainable.  Future blog posts will focus on the use of the new Date/Time API with JSpinner, leading up to a composite component for selecting a LocalDate.

Related Reading

The Java™ Tutorials:
Lambda Expressions
Method References
When to Use Nested Classes, Local Classes, Anonymous Classes, and Lambda Expressions

Advertisement

4 Responses to “Swing and Java 8”

  1. Jack said

    Thanks a lot.
    Very nice.

  2. Jack said

    This will also work:

    final JButton jButton = new JButton(“Click me”);

    jButton.addActionListener(event -> {

    });

    • Thank you, Jack.

      With Java 8, you no longer need to declare local variables as final. A variable may be ‘deemed’ final if it a value is assigned only once.

      Using a lambda expression with a block statement is covered in the linked Oracle tutorials.

      Darryl

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

 
%d bloggers like this: