Java Notes
Inner-class Listeners
Named inner class
Defining an inner class listener to handle events is a very popular style.
- Access. Use an inner class rather than an outer class to access instance variables of the enclosing class. In the example below, the myGreetingField can be referenced by the listener class. Because simple program listeners typically get or set values of other widgets in the interface, it is very convenient to use an inner class.
- Reuse. Unlike anonymous inner class listeners, it's easy to reuse the same listener for more than one control, eg, the click of a button might perform the same action as the equivalent menu item, and might be the same as hitting the enter key in a text field.
- Organization. It's easier to group all the listeners together with inner classes than with anonymous inner class listeners.
Examples
See Lesson 7 - DogYears - Listeners
Partial source code to share one inner class listener
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// File: : events/SomePanel.java // Purpose: Show use of named inner class listener. // Author : Fred Swartz // Date : 2005-09-05 import javax.swing.*; import java.awt.event.*; class SomePanel extends JPanel { private JButton myGreetingButton = new JButton("Hello"); private JTextField myGreetingField = new JTextField(20); //=== Constructor public SomePanel() { ActionListener doGreeting = new GreetingListener(); myGreetingButton.addActionListener(doGreeting); myGreetingField.addActionListener(doGreeting); // . . . Layout the panel. } /////////////////////////// Define inner class as listener. private class GreetingListener implements ActionListener { public void actionPerformed(ActionEvent e) { myGreetingField.setText("Guten Tag"); } } } |
Getting the name or actionCommand from a button
If you have a listener for a button, you might wonder why you need to get the text that labels the button. A common reason is that you have a number of buttons (eg, the numeric keypad on a calculator) that do almost the same thing. You can create one listener for all the keys, then use the text from the button as the value.
getActionCommand(). By default the getActionCommand() method of an ActionEvent will return the text on a button. However, if you internationalize your buttons so that the show different text depending on the user locale, then you can explicitly set the "actionCommmand" text to something else.
Let's say that you want to put the button value at the end of the inField
field as you might want to do for a calculator. You could do something like below
(altho checking for overflow).
JTextField inField = new JTextField(10); . . . // Create an action listener that adds the key name to a field ActionListener keyIn = new ActionListener() { public void actionPerformed(ActionEvent e) { // Get the name of the button String keyNum = e.getActionCommand(); // "1", "2", ... inField.setText(inField.getText() + keyNum); } }; // Create many buttons with the same listener JButton key1 = new JButton("1"); key1.addActionListener(keyIn); JButton key2 = new JButton("2"); key2.addActionListener(keyIn); JButton key3 = new JButton("3"); key3.addActionListener(keyIn); . . .