7.8 Swing-Beispiele
- Zu den Beispielen:
- Mausbewegungen
- Musterfenster
- Fachobjekt-Klasse AutoM zum Testen (Model-Klasse)
- Menü
7.8.1 Mausbewegungen
7.8.1.1 Klassendefinition des Hauptfensters mit Ereigniswächtern
Klasse MausbewegungenV |
---|
/* * MausbewegungenV.java */ package at.beringer.oopBuch.guiSwing; import javax.swing.*; import java.awt.*; import java.awt.event.*; /** Hauptfenster für Mausbewegungen. <br /> Die Mauskoordinaten werden in einem Textbereich gespeichert. <p> Anonyme Klasse: von 'MouseMotionAdapter' </p> <p> Im Paket 'at.beringer.oopBuch.guiSwingI18N' befindet sich eine vollständig internationalisierte - und parametrisierte (Fenstergröße) - Version dieser Fensterklasse. </p> <hr /> @since Mai 2000 @version Jänner 2002 (Swing ab JDK 1.3) @version <br />Juni 2012 (ohne ContentPane, ab JDK 6 möglich) @see ProgrammMausbewegungen @see at.beringer.oopBuch.guiSwingI18N.MausbewegungenV @see at.beringer.oopBuch.guiJavaFX.MausbewegungenV @author Beringer Alfred */ public class MausbewegungenV extends JFrame { // ------------------------------------------------------------------------- // Klassenkonstante // ------------------------------------------------------------------------- private static final String NEUEZEILE = System.getProperty("line.separator"); // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private JTextArea ausgabe = new JTextArea("Start", 8, 20); private JScrollPane ausgabeScroll = new JScrollPane(ausgabe); // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** Standardkonstruktor */ public MausbewegungenV() { this.setTitle("Swing-Fenster mit Mausbewegungen"); this.setSize(480, 260); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // initialisieren Textbereich ausgabe.setEditable(false); // Layout des Fensters definieren und Komponenten dem Fenster hinzufügen this.setLayout(new FlowLayout()); this.add(ausgabeScroll); // GUI-Komponenten bei Ereigniswächtern anmelden this.addMouseMotionListener(new MouseMotionAdapter() // *************************************************************** // anonyme (innere) Klasse // *************************************************************** { // ----------------------------------------------------------- // API-Methoden überschreiben // ----------------------------------------------------------- @Override public void mouseMoved(MouseEvent evt) { mausEreignis(evt); /* Ereignisobjekt mitgeben, falls Daten vom Ereignis benötigt werden */ } } // ********************************** Ende anonyme (innere) Klasse ); } // ************************************************************************* // Ereignisbehandlungsmethoden (private Methoden des Hauptfensters) // ************************************************************************* /** Methode für Mausbewegung. @param evt MouseEvent (von API-Methode 'mouseMoved' übernommen) */ private void mausEreignis(MouseEvent evt) { int x = evt.getX(); int y = evt.getY(); ausgabe.append(NEUEZEILE + "x=" + x + " y=" + y); } } |
Das Hauptprogramm entspricht dem von Kap.7.4.2 - mit der Klasse MausbewegungenV
.
- Hinweis:
- Bewegt man die Maus sehr schnell, so ist das Programm nicht in der Lage, alle gesendeten Mausereignisse zu verarbeiten - es "verschluckt" quasi etliche der Bewegungen.
7.8.2 Musterfenster mit vordefinierten grafischen Komponenten
7.8.2.1 Klassendefinition des Hauptfensters mit Ereigniswächtern
Klasse MusterfensterV |
---|
/* * MusterfensterV.java */ package at.beringer.oopBuch.guiSwing; import javax.swing.*; import javax.swing.border.*; import java.awt.*; import java.awt.event.*; import at.beringer.oopBuch.einfacheBsp.AutoM; /** Hauptfenster mit einfachen Standard-GUI-Komponenten. <p> Anonyme Klassen: von 'ActionListener' <br /> und von 'MouseAdapter' <br /> Model-Klasse: 'AutoM' (dient als Fachobjekt zum Testen dieser Fensterklasse) </p> <p> Im Paket 'at.beringer.oopBuch.guiSwingI18N' befindet sich eine vollständig internationalisierte - und parametrisierte (Fenstergröße) - Version dieser Fensterklasse. </p> <hr /> @since Jänner 2002 @version Juni 2006 (Refaktorierung) @version <br />Juni 2012 (ohne ContentPane, ab JDK 6 möglich) @see AutoM @see ProgrammMusterfenster @see at.beringer.oopBuch.guiSwingI18N.MusterfensterV @see at.beringer.oopBuch.guiJavaFX.MusterfensterV @author Beringer Alfred */ public class MusterfensterV extends JFrame { // ------------------------------------------------------------------------- // Klassenkonstante // ------------------------------------------------------------------------- private static final String NEUEZEILE = System.getProperty("line.separator"); // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private JLabel label = new JLabel("Label"); private JButton button1 = new JButton("Schaltfläche für Check"); private JButton button2 = new JButton("Schaltfläche für Liste"); private JCheckBox check1 = new JCheckBox("Check1", false); private JCheckBox check2 = new JCheckBox("Check2", true); private JCheckBox check3 = new JCheckBox("Check3", true); private String randtext = "Auto-Aktionen:"; private ButtonGroup buttongruppe = new ButtonGroup(); private JRadioButton radio1 = new JRadioButton("raufschalten", false); private JRadioButton radio2 = new JRadioButton("bremsen ", false); private JRadioButton radio3 = new JRadioButton("check3 aus! ", true); private JLabel labTxfeld = new JLabel(" \"return\" ... beendet die Eingabe: "); private JTextField textfeld = new JTextField("Textfeld", 20); private JLabel labTxbereich = new JLabel(" \"return\" ... nur Zeilenvorschub: "); private JTextArea textbereich = new JTextArea("Textbereich-Zeile1" + NEUEZEILE + "Zeile2", 4, 30); private JScrollPane textscroll = new JScrollPane(textbereich); private JLabel labListe1 = new JLabel("nur 1 einziges Element auswählbar: "); private DefaultListModel<String> liste1Model = new DefaultListModel<>(); private JList<String> liste1 = new JList<>(liste1Model); private JScrollPane liste1scroll = new JScrollPane(liste1); // Der Einfachheit halber fix codierte Daten für Listeninhalt private String[] liste1Daten = { "Liste1-Element1", "Liste1-Element2", "Liste1-Element3", "Liste1-Element4", "Liste1-Element5", "Liste1-Element6", "Liste1-Element7", "Liste1-Element8" }; private JLabel labListe2 = new JLabel("mehrere Elemente auswählbar: "); private DefaultListModel<String> liste2Model = new DefaultListModel<>(); private JList<String> liste2 = new JList<>(liste2Model); // Der Einfachheit halber fix codierte Daten für Listeninhalt private String[] liste2Daten = { "Liste2-Element1", "Liste2-Element2", "Liste2-Element3", "Liste2-Element4" }; private JLabel labCombo = new JLabel("Das ist eine Auswahl-Komponente: "); // Der Einfachheit halber fix initialisierte Daten für Listeninhalt private JComboBox<String> combo = new JComboBox<>(new String[] { "Combo-Element1", "Combo-Element2", "Combo-Element3" }); /** Aktionszähler */ private int zaehler = 0; /** Model-Klasse: Fachobjekt (zum Testen) */ private AutoM auto = new AutoM(); // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** Standardkonstruktor. <p> Das Erzeugen der einzelnen Teilfenster (Panels) und das Anmelden bei den Ereigniswächtern wird in private Methoden ausgelagert. </p> */ public MusterfensterV() { this.setTitle("Musterfenster mit vordefinierten Swing-Komponenten"); this.setSize(550, 700); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); initKomponenten(); initFenster(); initListener(); } // ------------------------------------------------------------------------- // Private Instanzmethoden // ------------------------------------------------------------------------- /** Eigenschaften der GUI-Komponenten definieren. */ private void initKomponenten() { // Optionsfelder buttongruppe.add(radio1); buttongruppe.add(radio2); buttongruppe.add(radio3); // Textfeld (einzeilig) textfeld.setEditable(true); // Textbereich (mehrzeilig) textbereich.setEditable(true); // Listen liste1.setVisibleRowCount(3); liste1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // Liste1 füllen (Zeilen einzeln hinzufügen) for (String zeile : liste1Daten) { liste1Model.addElement(zeile); } // Liste2 füllen (Zeilen einzeln hinzufügen) for (String zeile : liste2Daten) { liste2Model.addElement(zeile); } } // ------------------------------------------------------------------------- /** GUI-Komponenten zusammenbauen. */ private void initFenster() { JPanel poben1 = new JPanel(new FlowLayout()); JPanel poben2 = new JPanel(new FlowLayout()); JPanel poben3 = new JPanel(new FlowLayout()); JPanel poben = new JPanel(new GridLayout(0,1)); // 1 Spalte // Anzahl 0 bedeutet: "so viel wie nötig" JPanel pmitte4 = new JPanel(new FlowLayout()); JPanel pmitte5 = new JPanel(new FlowLayout()); JPanel pmitte6 = new JPanel(new FlowLayout()); JPanel pmitte7 = new JPanel(new FlowLayout()); JPanel pmitte8 = new JPanel(new FlowLayout()); JPanel pmitte = new JPanel(new GridLayout(0,1)); // 1 Spalte // Anzahl 0 bedeutet: "so viel wie nötig" // Initialisieren 'poben1' für Schaltflächen poben1.add(label); poben1.add(button1); poben1.add(button2); // Initialisieren 'poben2' für Kontrollkästchen poben2.add(check1); poben2.add(check2); poben2.add(check3); // Initialisieren 'poben3' für Optionsfelder initPoben3(poben3); // Initialisieren 'poben' poben.add(poben1); poben.add(poben2); poben.add(poben3); // Initialisieren Panels für 'pmitte' initPanelMitBeschriftung(pmitte4, labTxfeld, textfeld); initPanelMitBeschriftung(pmitte5, labTxbereich, textscroll); initPanelMitBeschriftung(pmitte6, labListe1, liste1scroll); initPanelMitBeschriftung(pmitte7, labListe2, liste2); initPanelMitBeschriftung(pmitte8, labCombo, combo); // Initialisieren 'pmitte' pmitte.add(pmitte4); pmitte.add(pmitte5); pmitte.add(pmitte6); pmitte.add(pmitte7); pmitte.add(pmitte8); // Layout des Fensters definieren und Komponenten dem Fenster hinzufügen this.setLayout(new BorderLayout()); this.add(poben,BorderLayout.NORTH); this.add(pmitte,BorderLayout.CENTER); } // ------------------------------------------------------------------------- /** Initialisieren 'poben3' für Optionsfelder. <p> Gezeigt wird beispielhaft die Verwendung eines Randes. </p> @param p 'poben3' für Optionsfelder */ private void initPoben3(JPanel p) { Border rand = BorderFactory.createLoweredBevelBorder(); Border randtitel = BorderFactory.createTitledBorder(rand, randtext); p.setBorder(randtitel); p.add(radio1); p.add(radio2); p.add(radio3); } // ------------------------------------------------------------------------- /** Initialisieren Panelzeile für eine GUI-Komponente mit Beschriftung. <br /> Die Beschriftung steht links - die Komponente rechts daneben. @param p Panel für GUI-Komponente mit Beschriftung @param beschriftung Beschriftung (Label) @param komponente GUI-Komponente */ private void initPanelMitBeschriftung(JPanel p, JLabel beschriftung, JComponent komponente) { JPanel plinks = new JPanel(new FlowLayout(FlowLayout.RIGHT)); JPanel prechts = new JPanel(new FlowLayout(FlowLayout.LEFT)); plinks.add(beschriftung); prechts.add(komponente); p.setLayout(new GridLayout(1,2)); p.add(plinks); p.add(prechts); } // ------------------------------------------------------------------------- /** GUI-Komponenten bei Ereigniswächtern anmelden. <p> Alle Ereigniswächter werden durch anonyme Klassen definiert. </p> <p> Die Tätigkeiten in den überschriebenen API-Methoden werden in private Methoden ausgelagert, wobei die 'Event'-Objekte der API-Methoden an diese privaten Methoden immer weitergegeben werden, sodass Daten vom Ereignis zur Verfügung stehen, falls diese benötigt werden. </p> */ private void initListener() { button1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { button1event(evt); } }); // button1 ist zuständig für Kontrollkästchen button2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { button2event(evt); } }); // button2 ist zuständig für Listen check1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { check1event(evt); } }); // nicht notwendig, zuständig ist button1! // check2 und check3 nicht angemeldet (zuständig ist button1) radio1.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { radio1event(evt); } }); radio2.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { radio2event(evt); } }); radio3.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { radio3event(evt); } }); textfeld.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { textfeldevent(evt); } }); liste1.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent evt) { liste1event(evt); } }); combo.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { comboevent(evt); } }); } // ************************************************************************* // Ereignisbehandlungsmethoden // ************************************************************************* /** Methode für Schaltfläche1. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void button1event(ActionEvent evt) { textbereich.append(NEUEZEILE + (++zaehler) + ". Action-Ereignis!"); auto.ausgeben("Schaltfläche1 gedrückt"); if (check1.isSelected()) { auto.ausgeben(" check1 hat Hakerl"); } else { auto.ausgeben(" check1 leer"); } if (check2.isSelected()) { auto.ausgeben(" check2 hat Hakerl"); } else { auto.ausgeben(" check2 leer"); } if (check3.isSelected()) { auto.ausgeben(" check3 hat Hakerl"); } else { auto.ausgeben(" check3 leer"); } } // ************************************************************************* /** Methode für Schaltfläche2. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void button2event(ActionEvent evt) { java.util.List<String> inhalte = liste2.getSelectedValuesList(); // seit Java 7.0 int[] indices = liste2.getSelectedIndices(); textbereich.append(NEUEZEILE + (++zaehler) + ". Action-Ereignis!"); auto.ausgeben("Schaltfläche2 gedrückt, ausgewählte Zeile von Liste1: "); auto.ausgeben(" " + liste1.getSelectedValue() + " (" + (liste1.getSelectedIndex()+1) + ". Zeile)"); auto.ausgeben(" ausgewählte Zeilen von Liste2: "); for (int i = 0; i < inhalte.size(); i++) { auto.ausgeben(" " + inhalte.get(i) + " (" + (indices[i]+1) + ". Zeile)"); } } // ************************************************************************* /** Methode für Kontrollkästchen1. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void check1event(ActionEvent evt) { textbereich.append(NEUEZEILE + (++zaehler) + ". Action-Ereignis!"); auto.ausgeben("check1 gedrückt"); } // ************************************************************************* /** Methode für Optionsfeld1. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void radio1event(ActionEvent evt) { textbereich.append(NEUEZEILE + (++zaehler) + ". Action-Ereignis!"); auto.ausgeben("radio1 gedrückt (raufschalten)"); auto.raufschalten(); auto.zeigeInhalt(); textbereich.append(NEUEZEILE + auto); } // ************************************************************************* /** Methode für Optionsfeld2. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void radio2event(ActionEvent evt) { textbereich.append(NEUEZEILE + (++zaehler) + ". Action-Ereignis!"); auto.ausgeben("radio2 gedrückt (bremsen)"); auto.bremsen(); auto.zeigeInhalt(); textbereich.append(NEUEZEILE + auto); } // ************************************************************************* /** Methode für Optionsfeld3. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void radio3event(ActionEvent evt) { textbereich.append(NEUEZEILE + (++zaehler) + ". Action-Ereignis!" + NEUEZEILE + auto); auto.ausgeben("radio3 gedrückt, check3 wird leer"); check3.setSelected(false); } // ************************************************************************* /** Methode für Textfeld. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void textfeldevent(ActionEvent evt) { textbereich.append(NEUEZEILE + (++zaehler) + ". Action-Ereignis!"); auto.ausgeben("Textfeld geändert: " + textfeld.getText()); } // ************************************************************************* /** Methode für Listenfeld1. @param evt MouseEvent (von API-Methode 'mouseClicked' übernommen) */ private void liste1event(MouseEvent evt) { auto.ausgeben("Mauswächter: Liste1, ausgewählte Zeile von Liste1: "); auto.ausgeben(" " + liste1.getSelectedValue() + " (" + (liste1.getSelectedIndex() + 1) + ". Zeile)"); auto.ausgeben(" Mausklick in " + (liste1.locationToIndex(evt.getPoint()) + 1) + ". Zeile"); } // ************************************************************************* /** Methode für Auswahlfeld. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void comboevent(ActionEvent evt) { textbereich.append(NEUEZEILE + (++zaehler) + ". Action-Ereignis!"); auto.ausgeben("Auswahl Combo: " + combo.getSelectedItem() + " (" + (combo.getSelectedIndex() + 1) + ". Zeile)"); } } |
Man beachte u.a. die Verwendung der beiden Layout-Manager (FlowLayout
und GridLayout
), sowie die Schachtelung der Komponenten mit Hilfe von Panels und die Verwendung von anonymen Ereigniswächterklassen.
Weiters beachte man auch die Verwendung der verschiedenen JCheckBox
-, JRadioButton
-, JList
- und JComboBox
-API-Methoden (wie isSelected
, setSelected
, getSelectedValue
, getSelectedValues
, getSelectedIndex
, getSelectedIndices
, locationToIndex
).
7.8.2.2 Klassendefinition des Fachobjekts (Model)
Die folgende von Auto
(siehe Kap.2) abgeleitete Klasse beinhaltet für Demonstrationszwecke die Trivialmethode 'ausgeben
'. Zum vereinfachten Testen werden im Konstruktor Auto
-Attribute initialisiert. Diese Klasse dient nur als Fachobjekt für dieses GUI-Beispiel und die nachfolgenden Beispiele - insbesondere sollte natürlich in einer GUI-Anwendung keine Ausgabe auf die Konsole erfolgen (man beachte auch die Hinweise von Kap.7.5.4.2):
Klasse AutoM |
---|
/* * AutoM.java */ package at.beringer.oopBuch.einfacheBsp; /** Model-Klasse für Testzwecke mit Trivialmethode 'ausgeben' und mit Initialisierungen von Attributen (insbesondere des Auto-Besitzers). <p> Diese Klasse dient nur als Fachobjekt ("model") für die GUI-Beispiele 'MusterfensterV', 'MenueV' und den 'Dialog'-Fensterklassen. </p> <hr /> @since Jänner 2002 @version Juli 2012 (PKW-Klasse umbenennen auf 'Auto'. Initialisierung des Besitzers im Konstruktor.) @see Auto @see at.beringer.oopBuch.guiSwing.MusterfensterV @see at.beringer.oopBuch.guiSwing.MenueV @see at.beringer.oopBuch.guiSwingI18N.DialogModalElternfensterV @see at.beringer.oopBuch.guiSwingI18N.DialogModalKindfensterV @see at.beringer.oopBuch.guiSwingI18N.DialogStandardV @author Beringer Alfred */ public class AutoM extends Auto { // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- public AutoM() { setMwstSatz(20); setFarbe("blau"); setBesitzer(new Person(1980, Person.MAENNLICH)); getBesitzer().aendernVorname("Hugo"); } // ------------------------------------------------------------------------- // Neue Instanzmethoden // ------------------------------------------------------------------------- /** Ausgabe eines übergebenen Textes auf die Standardausgabe. @param s auszugebender Text */ public void ausgeben(String s) { System.out.println(s); } } |
Hauptprogramm
Programmklasse ProgrammMusterfenster |
---|
/* * ProgrammMusterfenster.java */ package at.beringer.oopBuch.guiSwing; import javax.swing.JFrame; import javax.swing.SwingUtilities; import javax.swing.UIManager; /** Programmklasse (Applikation) für die Klasse 'MusterfensterV'. <hr /> @since Jänner 2002 @version Dezember 2004 (deprecated-Methode 'show' von Window-Klasse ersetzt) @see MusterfensterV @author Beringer Alfred */ public class ProgrammMusterfenster { // ------------------------------------------------------------------------- /** Der Einstiegspunkt für die Anwendung. @param args Kommandozeilenparameter */ public static void main(String[ ] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { System.err.println("System-LnF nicht gefunden"); } JFrame rahmen = new MusterfensterV(); rahmen.setVisible(true); } }); } } |
7.8.3 Aufbau und Verwendung von Menüs
7.8.3.1 Klassendefinition des Hauptfensters mit Ereigniswächtern
Klasse MenueV |
---|
/* * MenueV.java */ package at.beringer.oopBuch.guiSwing; import javax.swing.*; import java.awt.*; import java.awt.event.*; import at.beringer.oopBuch.einfacheBsp.AutoM; /** Hauptfenster mit Menüzeile, Menüs und Untermenüs. <p> Anonyme Klasse: von 'ActionListener' <br /> Model-Klasse: 'AutoM' (dient als Fachobjekt zum Testen dieser Fensterklasse) </p> <hr /> @since Mai 2000 @version Jänner 2002 (Swing ab JDK 1.3) @version <br />Juni 2012 (ohne ContentPane, ab JDK 6 möglich) @see AutoM @see ProgrammMenue @see Menue2V @see StandardfensterV @author Beringer Alfred */ public class MenueV extends JFrame { // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private JMenuBar menuezeile = new JMenuBar(); private JMenu menue1 = new JMenu("Auto"); private JMenuItem menueItem11 = new JMenuItem("neues Auto", 'N'); private JMenuItem menueItem12 = new JMenuItem("raufschalten", 'R'); private JMenuItem menueItem13 = new JMenuItem("runterschalten", 'U'); private JMenuItem menueItem14 = new JMenuItem("beschleunigen", 'S'); private JMenuItem menueItem15 = new JMenuItem("bremsen", 'B'); private JMenu menue2 = new JMenu("Menü2"); private JMenuItem menueItem21 = new JMenuItem("1. Menüeintrag Menü2"); private JCheckBoxMenuItem checkItem22 = new JCheckBoxMenuItem("2. Check-M2", true); private JCheckBoxMenuItem checkItem23 = new JCheckBoxMenuItem("3. Check-M2", false); private JMenu menue24 = new JMenu("4. Untermenü Menü2"); private JMenuItem menueItem241 = new JMenuItem("1. Menüeintrag Menü24"); private JMenuItem menueItem242 = new JMenuItem("2. Menüeintrag Menü24"); private ButtonGroup radiogruppe = new ButtonGroup(); private JRadioButtonMenuItem radioItem25 = new JRadioButtonMenuItem("5. Radio-M2", false); private JRadioButtonMenuItem radioItem26 = new JRadioButtonMenuItem("6. Radio-M2", true); private JRadioButtonMenuItem radioItem27 = new JRadioButtonMenuItem("7. Radio-M2", false); private JMenu menue3 = new JMenu("Hilfe"); private JMenuItem menueItem31 = new JMenuItem("Hilfethemen", 'H'); private JMenuItem menueItem32 = new JMenuItem("Info...", 'I'); private JButton button = new JButton("neues Auto"); /** Model-Klasse: Fachobjekt (zum Testen) */ private AutoM auto = new AutoM(); // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** Standardkonstruktor. <p> Das Erzeugen der Menüzeile, das Initialisieren der Schaltfläche sowie das Anmelden bei den Ereigniswächtern wird in private Methoden ausgelagert. </p> */ public MenueV() { this.setTitle("Swing-Fenster mit Menü"); this.setSize(480, 260); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Standardschaltfläche definieren (Eingabe mit RETURN-Taste möglich) this.getRootPane().setDefaultButton(button); initButton(); menuBarErstellen(); // Menüzeile in Fenster einfügen this.setJMenuBar(menuezeile); // Layout des Fensters definieren und Komponenten dem Fenster hinzufügen this.setLayout(new BorderLayout()); this.add(button,BorderLayout.SOUTH); initListener(); } // ------------------------------------------------------------------------- // Private Instanzmethoden // ------------------------------------------------------------------------- /** Erzeugen der Menüzeile. <br /> Die Reihenfolge der Hinzufügungen ('add') ist wesentlich. */ private void menuBarErstellen() { // Menüpunkte in Menü1 einfügen menue1.add(menueItem11); menue1.add(menueItem12); menue1.add(menueItem13); menue1.add(menueItem14); menue1.add(menueItem15); // Menüpunkte in Menü2 einfügen menue2.add(menueItem21); menue2.addSeparator(); menue2.add(checkItem22); menue2.add(checkItem23); menue2.addSeparator(); // Menüpunkte in Untermenü24 einfügen menue24.add(menueItem241); menue24.add(menueItem242); menue2.add(menue24); // Untermenü als Menüpunkt einfügen menue2.addSeparator(); // zusammengehörende Optionsfelder gruppieren radiogruppe.add(radioItem25); radiogruppe.add(radioItem26); radiogruppe.add(radioItem27); menue2.add(radioItem25); menue2.add(radioItem26); menue2.add(radioItem27); // Menüpunkte in Menü3 einfügen menue3.add(menueItem31); menue3.add(menueItem32); // Menüs in Menüzeile einfügen menuezeile.add(menue1); menuezeile.add(menue2); menuezeile.add(menue3); } // ------------------------------------------------------------------------- /** Schaltfläche initialisieren. */ private void initButton() { button.setFont(new Font("Monospaced", Font.BOLD, 32)); button.setForeground(Color.WHITE); button.setBackground(Color.MAGENTA); } // ------------------------------------------------------------------------- /** GUI-Elemente bei Ereigniswächtern anmelden. <p> Alle Ereigniswächter werden durch anonyme Klassen definiert. <br /> Die Tätigkeiten in den überschriebenen API-Methoden werden in private Methoden ausgelagert, wobei die 'Event'-Objekte der API-Methoden an diese privaten Methoden immer weitergegeben werden, sodass Daten vom Ereignis zur Verfügung stehen, falls diese benötigt werden. </p> */ private void initListener() { button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { neuesAuto(evt); // Event mitgeben, falls Daten vom Event benötigt werden } }); menueItem11.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { neuesAuto(evt); } }); menueItem12.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mItem12event(evt); } }); menueItem13.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mItem13event(evt); } }); menueItem14.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mItem14event(evt); } }); menueItem15.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mItem15event(evt); } }); menueItem21.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mItem21event(evt); } }); checkItem22.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mItem22event(evt); } }); // nicht angemeldet: checkItem23 // nicht angemeldet: menue24 radioItem25.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mItem25event(evt); } }); radioItem26.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mItem26event(evt); } }); // nicht angemeldet: radioItem27 menueItem31.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mItem31event(evt); } }); menueItem32.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { mItem32event(evt); } }); } // ************************************************************************* // Ereignisbehandlungsmethoden // ************************************************************************* /** Auto-Instanz erzeugen (über Menüauswahl oder über Schaltfläche). @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void neuesAuto(ActionEvent evt) { auto = new AutoM(); auto.zeigeInhalt(); } // ************************************************************************* /** Methode für Menü1 - Menüeintrag2. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void mItem12event(ActionEvent evt) { auto.raufschalten(); auto.zeigeInhalt(); } // ************************************************************************* /** Methode für Menü1 - Menüeintrag3. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void mItem13event(ActionEvent evt) { auto.runterschalten(); auto.zeigeInhalt(); } // ************************************************************************* /** Methode für Menü1 - Menüeintrag4. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void mItem14event(ActionEvent evt) { auto.beschleunigen(); auto.zeigeInhalt(); } // ************************************************************************* /** Methode für Menü1 - Menüeintrag5. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void mItem15event(ActionEvent evt) { auto.bremsen(); auto.zeigeInhalt(); } // ************************************************************************* /** Methode für Menü2 - Menüeintrag1. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void mItem21event(ActionEvent evt) { auto.ausgeben("1. Menüeintrag (Menü2) ausgewählt"); checkM23(); } // ************************************************************************* /** Methode für Menü2 - Menüeintrag2. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void mItem22event(ActionEvent evt) { auto.ausgeben("2. Menüeintrag (Menü2) ausgewählt"); checkM23(); } // ************************************************************************* /** Methode für Menü2 - Menüeintrag5. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void mItem25event(ActionEvent evt) { auto.ausgeben("5. Menüeintrag (Menü2) ausgewählt"); } // ************************************************************************* /** Methode für Menü2 - Menüeintrag6. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void mItem26event(ActionEvent evt) { auto.ausgeben("6. Menüeintrag (Menü2) ausgewählt"); } // ************************************************************************* /** Methode für Menü3 - Menüeintrag1. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void mItem31event(ActionEvent evt) { JOptionPane.showMessageDialog(this, "Achtung" + System.getProperty("line.separator") + "Hilfethemen noch nicht installiert!", "Info für MenueV", JOptionPane.WARNING_MESSAGE); } // ************************************************************************* /** Methode für Menü3 - Menüeintrag2. @param evt ActionEvent (von API-Methode 'actionPerformed' übernommen) */ private void mItem32event(ActionEvent evt) { JOptionPane.showMessageDialog(this, "Copyright 2001" + System.getProperty("line.separator") + "Beringer Alfred", "Info für MenueV", JOptionPane.INFORMATION_MESSAGE); } // ------------------------------------------------------------------------- // Hilfsmethoden zu den Ereignisbehandlungsmethoden // ------------------------------------------------------------------------- /** Prüfen der Option Menü2-Menüeintrag3. */ private void checkM23() { if (checkItem23.getState()) { auto.ausgeben(" 3. CheckMenüeintrag (Menü2) hat Hakerl"); } else { auto.ausgeben(" 3. CheckMenüeintrag (Menü2) hat kein Hakerl"); } } } |
Hauptprogramm
Das Hauptprogramm entspricht dem von Kap.7.4.2 - mit der Klasse MenueV
.
Man beachte die Vorgabe der Schriftart und der Schriftfarbe sowie der Hintergrundfarbe der Schaltfläche.
Da es nur 1 Schaltfläche gibt, wird diese mit Hilfe der Methode setDefaultButton(
jbutton)
aus der Klasse JRootPane
zur Standardschaltfläche gemacht, d.h. Drücken der Return-Taste ist gleichbedeutend mit Anklicken der Schaltfläche.
Untermenüs werden erstellt wie Menüs und dann einfach anstelle eines Menüeintrags ( add(
jMenuItem)
) in ein Menü eingefügt ( add(
jMenu)
). Dieses Menü wird damit automatisch zu einem Untermenü!
Menüs können so geschachtelt werden.
In der Klasse JCheckBoxMenuItem
wird das Setzen des Kontrollhäkchens gekapselt und immer korrekt durchgeführt - das Ereignis wird aber nicht an das Fenster weitergegeben (denn dieser 3. Menüeintrag wurde ja bei keinem Ereigniswächter angemeldet).
Allerdings kann das Programm immer dann, wenn es von einem beliebigen Ereignis benachrichtigt wird (z.B. nach Auswahl des 1. oder 2. Menüeintrags), den Zustand jeder beliebigen GUI-Komponente (z.B. des 3. Menüeintrags) prüfen.
Menüeinträge und Untermenüs können aktiviert und deaktiviert werden (Methode setEnabled
).
In diesem Beispiel wurden auch zweimal Standarddialoge verwendet - einfach mit Hilfe der Klassenmethode showMessageDialog
aus der Klasse JOptionPane
.
- Weiter
- zu den Java-GUI-Beispielen von Kapitel 7.9 (I18N - L10N - Parametrisierung)
- zu den Java-GUI-Beispielen von Kapitel 7.10 (Dialogfenster)
- zu Kapitel 8 (JDBC)
- zu den C#-Klassenbeispielen von Kapitel 9.19.1 (Exceptions)
- zu den C#-Klassenbeispielen von Kapitel 10 (Ein-/Ausgabe von Daten)
- zu Kapitel 12 (PL/I)
- zu Kapitel 13 (Reservierte Worte)
- zu den Java-GUI-Beispielen von Kapitel 7.10 (Dialogfenster)
- Zurück
- zum Anfang dieses Kapitels
- zum Inhaltsverzeichnis
- zu Kapitel 1
- zu den Klassenbeispielen von Kapitel 2
- zur Parameterübergabe (Kapitel 2.7.1)
- zu Kapitel 3
- zu den Klassenbeispielen von Kapitel 4
- zu den Java-Klassenbeispielen von Kapitel 5.19.1 (Exceptions)
- zu den Java-Klassenbeispielen von Kapitel 6 (Ein-/Ausgabe von Daten)
- zu den Java-GUI-Beispielen von Kapitel 7.4 (Einführung)
- zu den Java-GUI-Beispielen von Kapitel 7.5 (Fenster mit Label und Buttons)
- zum Inhaltsverzeichnis
- Zur
- Java-Dokumentation der Java-Beispiele