There are plenty of ways to add an ActionListener
, to a given JComponent
(that supports it's use). I have added some comments in the code snippets, to help explain them a bit better, and some links in the comments for future reference.
1.) If the class implements the ActionListener
interface, i.e. the class itself contains the actionPerformed(...)
method, then one can do it, in this manner:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Skeleton implements ActionListener {
private JFrame frame;
private JPanel contentPane;
private JButton button;
private void displayGUI() {
frame = new JFrame("Skeleton");
/*
* EXIT_ON_CLOSE is same as putting System.exit(0),
* which in some sense, doesnot allows one's
* application to terminate graciously.
*/
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
button = new JButton("This is a button.");
/*
* This is one way of attaching an ActionListener
* to the JButton, but the main disadvantage of
* this approach is, it breaks encapsulation,
* as you can see the public method, actionPerformed(),
* is lying free to be accessed by any code outside
* the scope of the class
*/
button.addActionListener(this);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Skeleton().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "BINGO!",
"Information: ", JOptionPane.INFORMATION_MESSAGE);
}
}
2.) If one doesn't wants to create unnecessary class
files. Then this approach, which uses, EventHandler
can be used:
import java.awt.*;
import java.awt.event.*;
import java.beans.EventHandler;
import javax.swing.*;
public class Example1 {
private JFrame frame;
private JPanel contentPane;
private JButton button;
private void displayGUI() {
frame = new JFrame("Skeleton");
/*
* EXIT_ON_CLOSE is same as putting System.exit(0),
* which in some sense, doesnot allows one's
* application to terminate graciously.
*/
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
button = new JButton("This is a button.");
/*
* This is another way of attaching
* an ActionListener to the JButton,
* the main advantage of this approach
* is, that one does not have to create
* a new class to handle events
* More info regarding the use of this
* approach, can be found on this link :
* http://docs.oracle.com/javase/tutorial/uiswing/events/generalrules.html
*/
button.addActionListener((ActionListener)
EventHandler.create(ActionListener.class
, Example1.this, "buttonAction", ""));
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Example1().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
public void buttonAction(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "BINGO!",
"Information: ", JOptionPane.INFORMATION_MESSAGE);
}
}
3.) If one is more concern about the concept of Encapsulation
, then this approach is beneficial:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Example2 {
private JFrame frame;
private JPanel contentPane;
private JButton button;
private ActionListener buttonActions =
new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(frame, "BINGO!",
"Information: ", JOptionPane.INFORMATION_MESSAGE);
}
};
private void displayGUI() {
frame = new JFrame("Skeleton");
/*
* EXIT_ON_CLOSE is same as putting System.exit(0),
* which in some sense, doesnot allows one's
* application to terminate graciously.
*/
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
button = new JButton("This is a button.");
/*
* This is another way of attaching
* an ActionListener to the JButton,
* the main advantage of this approach
* is, it adheres to encapsulation.
*/
button.addActionListener(buttonActions);
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Example2().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
4.) If one is more inclined towards creation of Anonymous Classes, then this approach can be used:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Example3 {
private JFrame frame;
private JPanel contentPane;
private JButton button;
private void displayGUI() {
frame = new JFrame("Skeleton");
/*
* EXIT_ON_CLOSE is same as putting System.exit(0),
* which in some sense, doesnot allows one's
* application to terminate graciously.
*/
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
button = new JButton("This is a button.");
/*
* This is the fourth way of attaching
* an ActionListener to the JButton,
* the main advantage of this approach
* is, it adheres to encapsulation, the
* public method remains hidden
* inside the Anonymous Class
* More info can be found on this link :
* http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
* The main disadvantage of this approach is
* that it doesnot gives you the privilege
* of separation of concerns, which can
* be done using the fifth approach,
* which is MVC - Pattern (Model-View-Controller)
* and moreover, it creates a hell lot of classes, in
* your project, which can lead to extra overhead
*/
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(frame, "BINGO!",
"Information: ", JOptionPane.INFORMATION_MESSAGE);
}
});
contentPane.add(button);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Example3().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
EDIT:
5.) This approach, includes using Action
instead of ActionListener
. This is to be used for sharing same functionality among various JComponent
s, which leads to code reusability
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Example4 {
private JFrame frame;
private JPanel contentPane;
private JMenuItem showMenuItem;
private JButton button;
private Action myActions;
/*
* This approach is basically used, when
* one wants to share the same functionality
* of different JComponents among each other,
* without writing redundant codes for each
* one of those components. Here JMenuItem
* and JButton are both using the same
* functionality, to perform the same task.
* More info can be found on this link:
* http://docs.oracle.com/javase/tutorial/uiswing/misc/action.html
*/
private class MyActions extends AbstractAction {
public MyActions(String title, String desc) {
super(title);
putValue(SHORT_DESCRIPTION, desc);
}
@Override
public void actionPerformed(ActionEvent ae) {
JOptionPane.showMessageDialog(frame, "BINGO!",
"Information: ", JOptionPane.INFORMATION_MESSAGE);
}
}
private void displayGUI() {
frame = new JFrame("Skeleton");
/*
* EXIT_ON_CLOSE is same as putting System.exit(0),
* which in some sense, doesnot allows one's
* application to terminate graciously.
*/
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
contentPane = new JPanel();
button = new JButton("This is a button.");
myActions = new MyActions("Show", "A small description");
button.setAction(myActions);
contentPane.add(button);
frame.setJMenuBar(getJMenuBar());
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JMenuBar getJMenuBar() {
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
showMenuItem = new JMenuItem(myActions);
fileMenu.add(showMenuItem);
menuBar.add(fileMenu);
return menuBar;
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
new Example4().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}