This article shows how easy it is to use Lambda expressions (a new feature of the upcoming Java SE 8 platform) in order to make the event handler code in Swing concise and succinct.

 

1. Classic Listener Code in Java Swing

Before Java 8, it’s very common that an anonymous class is used to handle click event of a JButton, as shown in the following code:

JButton button = new JButton("Click Me!");

button.addActionListener(new ActionListener() {
	public void actionPerformed(ActionEvent evt) {
		System.out.println("Handled by anonymous class listener");
	}
});

Here, an anonymous class that implements the ActionListener interface is created and passed into the addActionListener() method. And as normal, the event handler code is placed inside the actionPerformed() method.

 

2. Using Java Lambda expression for Listener Code in Swing

Because the ActionListener interface defines only one method actionPerformed(), it is a functional interface which means there’s a place to use Lambda expressions to replace the boilerplate code. The above example can be re-written using Lambda expressions as follows:

button.addActionListener(e -> System.out.println("Handled by Lambda listener"));

Oops! It’s pretty nice, isn’t it?. If we want to use multiple statements then wrap them inside a block as follows:

button.addActionListener(e -> {
	System.out.println("Handled Lambda listener");
	System.out.println("Have fun!");
});

 

3. A Swing Demo program

Here’s code of a demo program which is a JFrame containing only one button which registers its click event with three different listeners:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * This simple Swing program demonstrates how to use Lambda expressions in
 * action listener.
 *
 * @author www.codejava.net
 */
public class ListenerLambdaExample extends JFrame {

	private JButton button = new JButton("Click Me!");

	public ListenerLambdaExample() {
		super("Listener Lambda Example");

		getContentPane().setLayout(new FlowLayout());
		getContentPane().add(button);

		button.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent evt) {
				System.out.println("Handled by anonymous class listener");
			}
		});

		button.addActionListener(e -> System.out.println("Handled by Lambda listener"));

		button.addActionListener(e -> {
			System.out.println("Handled Lambda listener");
			System.out.println("Have fun!");
		});

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300, 100);
		setLocationRelativeTo(null);
	}

	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				new ListenerLambdaExample().setVisible(true);
			}
		});
	}
}

Screenshot of the program:

Lambda Listener Swing Demo

Output in the console when the button is clicked:

Handled Lambda listener
Have fun!
Handled by Lambda listener
Handled by anonymous class listener

 

Related Tutorials:

 

Other Recommended Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He began programming with Java back in the days of Java 1.4 and has been passionate about it ever since. You can connect with him on Facebook and watch his Java videos on YouTube.



Attachments:
Download this file (ListenerLambdaExample.zip)ListenerLambdaExample.zip[Java source file]4 kB

Add comment

   


Comments 

#5GICHINI2020-01-22 02:45
Good work here.Rich examples
Quote
#4Adam Erickson2019-07-19 11:52
Just what I was looking for. My last company was so afraid of using Lamdas. I don't understand why. It makes things so more organized.

This was better laid out than anything on StackOverflow.
Quote
#3Simon2017-01-04 10:12
It would be interesting to see your take on how these listeners can then be removed from the observable object.

Lots of examples of adding lambda and method-reference listeners to observables, but nothing on how they can be removed - which is necessary in a non-trivial system.
Quote
#2Nam2015-03-07 10:23
Hi Tim,

Thanks for your useful advice.
Quote
#1Tim2015-03-03 14:05
If you move the setVisible(true) into the constructor (say, after setLocationRelativeTo), you can convert main into a lambda as well:

SwingUtilities.invokeLater(LambdaExample::new);

Which is also cleaner.
Quote