13.02.02 Der JButton

Im letzten Kapitel haben Sie die Container für alle Steuerelemente kennengelernt, JFrame und JDialog. Doch diese Container sind ohne Steuerelemente nutzlos. Unter Steuerelementen versteht man z.B.: Buttons, Textfelder etc. Also alles, womit das Programm grafisch gesteuert werden kann. In diesem Kapitel widmen wir uns einem der wichtigsten Steuerelemente, dem Button.

Der JButton

Der Button ist eines der wichtigsten Steuerelemente in der Oberflächen-Programmierung. In Swing wird ein Button von der Klasse JButton im Paket javax.swing repräsentiert.
Ein JButton hat fünf Konstruktoren, vier davon werden im Folgenden beschrieben:

  • JButton(): Erzeugt einen leeren JButton ohne Text und Bild.
  • JButton(Icon icon): Erzeugt einen Button ohne Text mit Icon.
  • JButton(String text): Erzeugt einen Button ohne Icon mit Text.
  • JButton(String text, Icon icon): Erzeugt einen Button mit Icon und Text. Der Icon ist links vom Text ausgerichtet.

Um eine Kompontente (hier einen Button) auf das Fenster zu setzen, müssen wir die Methode add(Component c) des Frames aufrufen. Am Parametertyp Component sehen Sie, dass alle Komponenten, die Sie auf einen JFrame setzen können, eine Oberklasse haben.

Exkurs – Die Klasse Component

Die Klasse Component ist die Oberklasse für alle Komponenten des AWT und von Swing. Dazu gehören auch die Fensterklassen, zum Beispiel JFrame und JDialog. Ja, auch diese Klassen lassen sich theoretisch auf einen anderen Frame setzen. In der Praxis jedoch wird eine IllegalArgumentException geworfen, mit der Nachricht, dass man ein Fenster nicht auf einen Container setzen kann.
Da Component aus dem Paket java.awt kommt, können auch Komponenten aus dem AWT auf Swing-Frames gesetzt werden, was Sie aber nicht tun sollten, da Swing-Komponenten „leichte“ und AWT-Komponenten „schwere“ sind, was zu unerwünschten Effekten führen kann. (Mehr dazu im Wiki-Artikel: Warum nicht AWT und Swing mischen?)

Alle Methoden wie setSize(int width, int height), setLocation(int x, int y), setBackground(Color c), etc. kommen ebenfalls von Component und haben bei allen Komponenten die gleiche Syntax. Deswegen wird in den nächsten Kapiteln nicht näher auf diese Methoden eingegangen.

Mit diesem Wissen können wir nun unseren ersten Button auf einen Frame setzen:

package de.jbb.jbutton;
import javax.swing.JFrame;
import javax.swing.JButton;

public class FirstButtonTest{

  public static class Main(String[] args){

    JFrame frame = new JFrame("JFrame mit JButton");
    frame.setBounds(500,500,100,100);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JButton jbutton = new JButton("Mein erster Button");
    jbutton.setBounds(3,3,50,50);

    frame.add(jbutton);
    frame.setVisible(true);
  }
}

Nach dem Sie den Code ausgeführt haben, können Sie sehen, dass der Button alles andere tut, als sich Ihren Größen- und Platzierungsangaben zu unterwerfen. Wenn Sie den Frame jetzt größer oder kleiner ziehen, sehen Sie, dass der Button die Verändungen immer mitmacht und immer so groß ist wie der Frame selbst. Dies liegt an den so genannten Layout-Managern, die standardmäßig das Platzieren der Komponenten übernehmen. Mehr dazu erfahren Sie im nächsten Kapitel, für dieses Kapitel reicht ein einzelner großer Button.

Ein Button mit Aktion

Dazu braucht der Button einen so genannten ActionListener, der auf Aktionen am Button wartet. Dieser ist als Schnittstelle im Paket java.awt.event mitgeliefert. Beim ActionListener müssen wir nur eine Methode implementieren, nämlich actionPerformed(ActionEvent e). Die JVM ruft automatisch diese Methode auf, sobald der Button gedrückt wurde (nicht wenn er gerade gedrückt ist). Über das ActionEvent lassen sich Eigenschaften des Klick-Ereignisses ermitteln, beispielsweise wann der Button angeklickt wurde. In unserem Beispiel wollen wir aber nur den Text „Hello World“ auf der Kommandozeile ausgeben, sobald der Button gedrückt wurde.

package de.jbb.jbutton;

import  java.awt.event.ActionListener;
import  java.awt.event.ActionEvent;

public class MyActionListener implements ActionListener {

  @Override public void actionPerformed(ActionEvent e){

     System.out.println("Hello World");
   }
}

Nun müssen wir diesen Listener nur noch dem Button zuweisen:

myButton.addActionListener(new MyActionListener());

Wenn Sie den Code jetzt ausführen und auf den Button drücken, erscheint danach die Meldung „Hello World“ auf der Kommandozeile.
Haben Sie viele Buttons in einem Programm, die zum Teil wirklich nur sehr einfache Codes beim Druck-Event auszuführen haben, ist obige Methode sehr zeitaufwändig und führt zu vielen sehr kleinen Klassen. Darum kann man das Ganze auch abkürzen, in dem eine anoyme Klasse erstellt wird:

myButton.addActionListener(new ActionListener() {

  @Override public void actionPerformed(ActionEvent e) {
    System.out.println("Hello World");
  }
});

Diese Methode hat den Vorteil, dass nicht so viele kleine Klassen entstehen und die ActionListener direkten Zugriff auf die entsprechenden Attribute und Variablen haben. Dies ist bei ersterer Methode nur über Konstruktoren möglich. Allerdings ist erstere Methode besser, wenn es sehr viele Buttons mit ähnlicher Funktionen im Programm gibt, Stichwort Wiederverwendbarkeit. Letztendlich ist es aber Geschmackssache, welche Methode Sie wählen.

(Mehr über JButton und die Varianten der Ereignisverarbeitung haben wir im Wiki im Artikel JButton zusammengestellt.)

An der Methode addActionListener(ActionListener a) sehen Sie, dass man mehrere ActionListener hinzufügen kann. In der Regel werden diese dann in umgekehrter Reihenfolge wie sie hinzugefügt wurden aufgerufen.

Wenn Sie Ihren Button aus dem Code aus klicken wollen, gibt es die Methode doClick(), oder auch wahlweise mit dem Parameter time, der festlegt, wie lange der Button gedrückt werden soll. Bei beiden Methodenaufrufen werden die Buttons animiert.

Button mit eigenem Cursor

Zuweilen möchte man, dass sich der Cursor über Buttons in eine Hand verwandelt. Dies lässt sich mit der Methode setCursor(Cursor c) erreichen.
Die Klasse Cursor liegt im Paket java.awt. Einen Handcursor erstellt man so:

Cursor hand = new Cursor(Cursor.HAND_CURSOR);

Die anderen Konstanten kann man in der API-Dokumentation nachlesen.
setCursor(Cursor c) ist ebenfalls eine Methode von Component, also auch auf alle anderen Komponenten anwendbar.

Buttons fernsteuerbar machen

Oftmals sehen Sie, dass ein Buchstabe im Text der Buttons unterstrichen ist. Dies signalisiert, dass Sie mit der Tastenfolge Alt+Buchstabe den Button aktivieren können. Diese Funktion nennt man Mnemonic und kann auch mit Java verwendet werden. Wenn Sie beispielsweise den Button „Fortfahren“ mit Alt+F erreichen wollen, so rufen Sie die Methode setMnemonic(char c) des Buttons auf:

continueButton.setMnemonic('F');

Wenn der übergebene char im Text des Buttons vorhanden ist, wird er unterstrichen. Manchmal kann es hilfreich sein, einen anderen Buchstabe zu unterstreichen, als der, den Java ausgewählt hat (der erste vorkommende, es wird nicht auf Groß-/Kleinschreibung geachtet). So mag es schöner sein, in einem Button mit dem Text „Save As“ und dem Mnemonic ‚A‘, das zweite „A“ zu unterstreichen. In diesem Fall rufen Sie diese Methode auf:

saveButton.setDisplayedMnemonicIndex(5);

Der JButton und seine Größe

In diesem Kapitel haben Sie gelernt, wie Sie einen Button erstellen und ihm sagen können, was er im Falle eines Klicks tun soll. Aber der Button hat nicht auf Ihre Angaben bezüglich Positionierung und Größe reagiert. Diese Eigenschaft des Buttons und übrigens auch aller anderen Steuerelemente wird ihnen im nächsten Kapitel über die LayoutManager erklärt.

Ähnliche Beiträge