Wie reagiert ein Button beim Anklicken?
Da man normalerweise nicht an allen ausgesandten Ereignissen
interessiert ist, muss man diejenigen abfangen, auf die reagiert
werden soll. Hierzu steht für jede spezielle Ereignisart
ein sog. Listener zur Verfügung, bei dem man die
das Ereignis erzeugende Komponente anmelden muss. Der ActionListener
selbst ist eine Schnittstelle mit einer Methode, void
actionPerformed(ActionEvent e)
, die von der Klasse
implementiert werden muss, die als Listener fungieren soll.
In den folgenden Beispielen werden hierzu die gängigsten
Verfahren anhand einer einfachen Schaltfläche vorgestellt,
die bei Betätigung einen kurzen Text auf der Konsole
ausgibt.
Listener und Button in der selben Klasse
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class ButtonEventClass implements ActionListener {
private JButton button;
public ButtonEventClass(){
init();
}
private void init() {
JFrame frame = new JFrame("Button-Test");
button = new JButton("click mich!");
button.addActionListener(this);
frame.add(button);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button){
System.out.println("Button geklickt!");
}
}
public static void main(String[] args){
SwingUtilities.invokeLater(() -> new ButtonEventClass());
}
}
Im ersten Beispiel implementiert die Klasse, die den Button
enthält, den Listener selbst. Somit muss sie selbst
auch die Methode actionPerformed()
enthalten,
die als Parameter ein ActionEvent
übergeben bekommt.
Der Ereignisauslöser muss
jetzt durch die Methode addActionListener()
mit
dem Listener verbunden werden. Als Parameter wird ein
Verweis auf das aktuelle Objekt der eigenen Klasse
übergeben, da die Klasse ja selbst den Listener
implementiert.
Listener in innerer Klasse
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class ButtonEvent2Class {
private JButton button;
public ButtonEvent2Class(){
init();
}
private void init() {
JFrame frame = new JFrame("Button-Test");
button = new JButton("click mich!");
button.addActionListener(new ButtonLauscher());
frame.add(button);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
class ButtonLauscher implements ActionListener {
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button){
System.out.println("Button geklickt!");
}
}
}
public static void main(String[] args){
SwingUtilities.invokeLater(() -> new ButtonEvent2Class());
}
}
Im zweiten Beispiel wird der ActionListener in einer eigenen
inneren
Klasse realisiert, von der eine Instanz mit dem
Button verbunden wird. Wie im ersten Beispiel auch kann mit
der Methode ActionEvent.getSource()
die
Ereignisquelle ermittelt werden. Auf diese Weise kann ein
Listener mehrere Ereignisse überwachen.
Listener in separater Klasse
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class ButtonEvent3Class {
private JButton button;
public ButtonEvent3Class() {
init();
}
private void init() {
JFrame frame = new JFrame("Button Test");
button = new JButton("click mich!");
button.addActionListener(new ButtonLauscher());
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new ButtonEvent3Class());
}
}
class ButtonLauscher implements ActionListener {
public void actionPerformed(ActionEvent e) {
System.out.println("Button '" + ((JButton) e.getSource()).getText() + "' geklickt.");
}
}
Das dritte Beispiel entspricht in den Grundzügen dem
zweiten. Jedoch ist der Listener nicht als innere, sondern
als selbstständige Klasse realisiert. Da hier die
Instanz des auslösenden JButton
nicht mehr
zur Verfügung steht, ist ein Abgleich mit
if(e.getSource() == button){ //...
wie in Beispiel 2 so nicht mehr möglich. Die Lösung zeigt die Version 4. In dieser wird der Listener-Klasse das Objekt des auslösenden Buttons als Parameter übergeben und im Konstruktor an eine Instanzvariable weitergeleitet. Diese kann dann auf die bekannte Weise abgefragt werden.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class ButtonEvent4Class {
private JButton button;
public ButtonEvent4Class(){
init();
}
private void init() {
JFrame frame = new JFrame("Button Test");
button = new JButton("click mich!");
button.addActionListener(new ButtonLauscher4(button));
frame.add(button);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args){
SwingUtilities.invokeLater(() -> new ButtonEvent4Class());
}
}
class ButtonLauscher4 implements ActionListener {
JButton button;
public ButtonLauscher4(JButton button){
this.button = button;
}
public void actionPerformed(ActionEvent e) {
if(e.getSource() == button)
System.out.println("Button '" + ((JButton)e.getSource()).getText() + "' geklickt.");
}
}
Listener in anonymer Klasse
Die für einfache Fälle naheliegendste Möglichkeit besteht jedoch darin, den Listener in einer anonymen Klasse zu implementieren.
import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.SwingUtilities; public class ButtonEventAnonClass { private JButton button; public ButtonEventAnonClass() { init(); } private void init() { JFrame frame = new JFrame("Button-Test"); button = new JButton("click mich!"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System.out.println("Button geklickt!"); } }); button.addActionListener(e -> System.out.println("Button geklickt")); frame.add(button); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(200, 200); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(() -> new ButtonEventAnonClass()); } }
Listener als Lambda Ausdruck
Ab Java 8 kann statt der anonymen Klasse auch ein Lambda-Ausdruck
verwendet werden, da es sich beim ActionListener
um ein functional interface
handelt. Der
Listener-Aufruf kann dann in der folgenden Weise formuliert
werden.
//... button = new JButton("click mich!"); button.addActionListener(e -> System.out.println("Button geklickt")); //...
Wenn Ihnen javabeginners.de gefällt, freue ich mich über eine Spende an diese gemeinnützigen Organisationen.