Java Swing Kontrollelemente

Willemers Informatik-Ecke

Ereignisse

Die Kontrollelemente lösen Ereignisse aus, die eine Klasse auffängt, die das Interface ActionListener implementiert. Praktischerweise verwendet man dazu auch gleich die Klasse, die das Fenster erstellt. Das Ereignis löst den Aufruf der Methode actionPerformed aus, die von der Klasse implementiert werden muss. Dazu muss sie allerdings für jedes Element mit dem Aufruf addActionListener angemeldet worden sein.

Innerhalb der Methode actionPerformed kann sie aus dem Paramter ActionEvent mit mehreren Methoden Details zu dem Ereignis ermitteln.

  • Object getSource()
    liefert das Objekt, dass das Ereignis auslöste
  • String getActionCommand()
    liefert einen String, der das Ereignis beschreibt.
  • int getModifiers()
    liefert die Kontrolltasten, die während des Ereignisses gedrückt waren
  • long getWhen()
    liefert einen Zeitstempel
  • String paramString()
    liefert einen Paramter als String

Buttons

Die einfachste aktive Kontrollelement ist der Button, bei Swing JButton genannt. Mit dem Aufruf addActionListener(this) wird angemeldet, dass diese Klasse beauftragt ist, die Ereignisse zu fangen, die der Button auslöst. Dazu implementiert die Klasse das Interface ActionListener.

Wer ActionListener implementiert, muss die Methode actionPerformed definieren. Sie wird von der Laufzeitumgebung aufgerufen, wenn ein Ereignis eintrifft. Der Parameter dieser Methode ist ein ActionEvent, das Informationen liefert, die zur Verarbeitung hilfreich sind, insbesondere, welcher Button eigentlich gedrückt wurde.

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

public class ButtonAction extends JFrame implements ActionListener {

    private JButton click;

    ButtonAction() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        getContentPane().setLayout(new BorderLayout());
        click = new JButton("Drück mich!");
        click.addActionListener(this);
        getContentPane().add(click, BorderLayout.CENTER);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new ButtonAction();
    }

    public void actionPerformed(ActionEvent ev) {
        if (ev.getSource()==click) {
            JOptionPane.showMessageDialog(null, "Sehr druckvoll!");
        }
    }
}

Der Button hat einen Haken

Das Kontrollelement JCheckBox ist ein Button, der Wahr-Falsch-Entscheidungen grafisch umsetzt. Der Konstruktor übernimmt üblicherweise den Text, der die JCheckBox darstellt. Ansonsten verhält er sich weitgehend wie ein normaler Button.

Auch der Checkbox kann ein ActionListener zugewiesen werden, der ebenso reagiert, wie der des Buttons. Die Aktion wird sowohl durch das Setzen wie auch durch das Wegnehmen des Hakens ausgelöst.

Zusätzlich zum Button hat die JCheckBox einen Status. Sie kann selektiert sein, also einen Haken tragen oder eben nicht. Dieser Haken wird entweder vom Benutzer gesetzt oder aber von der Applikation durch Aufruf der Methode setSelected. Als Paramter erwartet die Methode einen booleschen Wert, der angibt, ob der Haken gesetzt ist oder nicht.

  • void setSelected(boolean haken)
    setzt oder löscht einen Haken, je nach Parameter haken.
  • boolean isSelected()
    prüft, ob der Haken gesetzt ist.

Eingabefelder

Für die Eingabe von Daten gibt es das Kontrollelement JTextField. Der Benutzer kann dort eine Zeile eintippen. Die Eingabe wird mit der Methode getText ausgelesen. Das Ergebnis steht dann in einer Variable vom Typ String. Bei Zahleneingaben muss der String in eine Zahlenvariable umgewandelt werden.
JTextField eingabeFeld = new JTextField();
Die wichtigsten Arbeiten sind das Auslesen einer Benutzereingabe mit getText. Hin und wieder möchte man einen Wert vorgeben. Dann wird die Methode setText verwendet.
eingabeFeld.setText("1.4142135");
String inhalt = eingabeFeld.getText();
Abwandlungen sind das JPasswordField, mit dem man eben Passwörter eingeben lassen kann. Die Eingabe wird dann verdeckt.

Das JTextArea stellt ein mehrzeiliges Eingabefeld dar. Damit kann leicht ein kleiner Editor in die Anwendung eingebaut werden. Wird der Inhalt als nicht editierbar gesetzt, kann man damit leicht längere Passagen wie Copyrightvermerke anzeigen.

  • void setEditable(boolean)
    boolean isEditable()
    Setzt und prüft die Editierbarkeit des Eingabefelds.
  • void setHorizontalAlignment(int)
    int getHorizontalAlignment()
    Setzt und prüft die horizontale Ausrichtung. Als Parameter werden die Konstanten JTextField.LEADING für linksbündig, JTextField.CENTER für zentriert oder JTextField.TRAILING für rechtsbündig verwendet.

Fokus

Wenn ein Kontrollelement die Tastenkontrolle hat, hat es den Fokus. Verlässt der Anwender das Kontrollelement, so verliert es den Fokus. Bei Eingabefeldern ist das Ereignis, dass es den Fokus verliert von hohem Interesse, wenn man beispielsweise die Eingabe prüfen will oder Zwischenergebnisse berechnen will. Dazu muss ein FocusListener aufgesetzt werden. Das folgende Beispiel ist ein Programm mit zwei Eingabefeldern, deren Fokus beobachtet wird. Zwischen den beiden Eingabefeldern wird ein TextArea-Feld benutzt, um die Ereignisse anzuzeigen. Bei der Gelegenheit wird noch gezeigt, wie das JTextArea-Element in ein JScrollPane gesteckt wird, das dann die Verwaltung der Schiebebalken übernimmt, wenn der Textinhalt größer wird als der Programmausschnitt anzeigt.
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.event.*;

public class TestFocus extends JFrame implements FocusListener {
    JTextArea anzeige;
    JTextField txtOben, txtUnten;

    TestFocus() {
        setDefaultCloseOperation(EXIT_ON_CLOSE); // Schließen bewirkt Ende
        setLayout(new BorderLayout());           // Layout auf Border festlegen
        anzeige = new JTextArea();               // Multi-Line-Edit als Anzeige
        anzeige.setEditable(false);
        JScrollPane scrollRahmen = new JScrollPane(anzeige); // Schiebebalken um Anzeige
        txtOben = new JTextField();              // Eingabefeld anlegen
        txtOben.addFocusListener(this);          // FocusListener anmelden
        txtUnten = new JTextField();
        txtUnten.addFocusListener(this);
        add(scrollRahmen, BorderLayout.CENTER);  // Elemente ins Layout bringen
        add(txtOben, BorderLayout.NORTH);
        add(txtUnten, BorderLayout.SOUTH);
        setSize(400, 300);                       // Rahmen groß machen
        setVisible(true);                        // Rahmen sichtbar machen
    }

    @Override public void focusGained(FocusEvent e) {  // Focus erhalten
        if (e.getSource() == txtOben) {          // wer hat das Ereignis ausgelöst?
            anzeige.append("Focus erhalten: txtOben\n");
        } else if (e.getSource() == txtUnten) {
            anzeige.append("Focus erhalten: txtUnten\n");
        }
    }

   @Override public void focusLost(FocusEvent e) {  // Focus verloren
        if (e.getSource() == txtOben) {          // wer hat das Ereignis ausgelöst?
            anzeige.append("Focus verloren: txtOben\n");
        } else if (e.getSource() == txtUnten) {
            anzeige.append("Focus verloren: txtUnten\n");
        }
    }

    public static void main(String[] args) {
        new TestFocus();                         // gib Gas!
    }
}

RadioButtons

Radiobuttons haben ihren Namen von den Stationstasten am Radio. Es kann immer nur ein Sender gleichzeitig laufen. Egal wie viele Tasten also am Radio existieren, es kann immer nur einer gedrückt sein.

Die einzelnen Buttons sind Objekte der Klasse JRadiobutton.

JRadioButton radioMaennlich = new JRadioButton("männlich");
JRadioButton radioWeiblich = new JRadioButton("weiblich");
Sie können nun in ein Fenster eingesetzt und angeklickt werden. Allerdings kann man derzeit noch sowohl männlich als auch weiblich sein. Um die typische Radio-Funktion zu erreichen, müssen die Buttons einer ButtonGroup zugeordnet werden.
ButtonGroup grpGeschlecht = new ButtonGroup();
grpGeschlecht.add(radioMaennlich);
grpGeschlecht.add(radioWeiblich);
radioMaennlich.setSelected(true);
Hier ein komplettes Beispiel:

import java.awt.Container;
import java.awt.Color;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JRadioButton;
import javax.swing.ButtonGroup;

public class RadioButton extends JFrame {

    RadioButton() {
        Container pane = this.getContentPane();
        pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));

        // Setze die Buttons mit Beschriftung
        JRadioButton radioGelb = new JRadioButton("gelb");
        JRadioButton radioRot = new JRadioButton("rot");
        JRadioButton radioGruen = new JRadioButton("grün");
        JRadioButton radioBlau = new JRadioButton("blau");
        // Erzeuge die Gruppe zwischen denen umgeschaltet wird
        ButtonGroup gruppe = new ButtonGroup();
        gruppe.add(radioGelb);
        gruppe.add(radioRot);
        gruppe.add(radioGruen);
        gruppe.add(radioBlau);
        // Setze sie auf das Panel
        pane.add(radioGelb);
        pane.add(radioRot);
        pane.add(radioGruen);
        pane.add(radioBlau);

        radioRot.setSelected(true); // Auswahl vorgeben

        // Setzen des passenden Hintergrunds
        radioRot.setBackground(Color.red);
        radioGelb.setBackground(Color.yellow);
        radioBlau.setBackground(Color.blue);
        radioGruen.setBackground(Color.green);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        new RadioButton();
    }
}
Natürlich kann für jeden RadioButton auch ein ActionListener definiert werden. Das ist nützlich, wenn beim Wechsel der Auswahl beispielsweise sofort ein anderer Hinweistext erscheinen soll.

Ob ein RadioButton gedrückt ist, kann mithilfe der Methode isSelected() ermittelt werden.

Combobox zur Auswahl aus einer Liste

Eine Combobox könnte man auch als Klappliste bezeichnen. Der ausgewählte Eintrag der Liste ist offen sichtbar, die anderen Optionen klappen heraus, wenn man den Button des Elements anklickt.

Die Combobox eignet sich als Ersatz für Radiobuttons oder als Ersatz für eine Liste, die nur eine Auswahl zulässt.

String[] strWahl = { "Anton", "Berta", "Caesar", "Dora" };
JComboBox wahl = new JComboBox(strWahl);
Bei der Auswertung wird einfach abgefragt, welches Feld ausgewählt war. Der Rückgabewert ist der Index der Auswahl, beginnend bei 0.
int index = wahl.getSelectedIndex();
Man kann auch der Combobox einen ActionListener zuweisen. Dann kann das Programm auf jede Änderung in der Box reagieren.
wahl.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    JComboBox jcmbType = (JComboBox) e.getSource();
    String cmbType = (String) jcmbType.getSelectedItem();
    label.setIcon(new ImageIcon("" + cmbType.trim()) + ".jpg"));
  }
});
Die Methoden von JComboBox:
  • getSelectedItem()
    gibt String zurück
  • getSelectedIndex()
    gibt die Nummer zurück
  • setEditable(true)
    erlaubt das Editieren der Einträge
  • setAlignmentX(Component.LEFT_ALIGNMENT)
    waagerechte Ausrichtung der Einträge
Als Elemente können Arrays oder Vektoren verwendet werden. Der Konstruktor akzeptiert auch ein ComboBoxModel.

Ein naher Verwandter der Combobox ist die JList. Das ist eine Liste, die nicht ausklappt, sondern einen größeren Raum für alle Zeilen einnimmt.

Strengere Typisierung

In den neueren Java-Versionen wird es immer eine Warnung geben, wenn man JComboBox auf die oben beschriebene Weise benutzt. Der Hintergrund ist, dass die Schnittstellen Object verwenden. Für die korrekte Typisierung wird der JComboBox der Typ in spitzen Klammern beigefügt. In den meisten Fällen wird das String sein.

String[] strWahl = { "Anton", "Berta", "Caesar", "Dora" };
JComboBox<String> wahl = new JComboBox<String>(strWahl);


Homepage - Java (C) Copyright 2011, 2015 Arnold Willemer