SWING Literatur Ausgewählte Implementierungsprobleme Rebecca Tiarks 15. Januar 2009 1 / 56 SWING Literatur Inhaltsverzeichnis 1 SWING 2 / 56 SWING Literatur AWT grafische Benutzeroberfläche (GUI) erste API von Sun AWT bietet GUI-Komponenten, Operationen zum Zeichnen und zur Ereignisbehandlung. sehr einfach gehalten 3 / 56 SWING Literatur Peer-Klassen jede grafische Komponente wird auf darunterliegende Komponente der Plattform abgebildet Peer-Klassen Schaltfläche leitet Visualisierung und Interaktion an eine Peer-Klasse auf der Betriebssystemseite weiter. dadurch sollen Theoretisch alle AWT-Anwendungen dem look and feel der Plattform entsprechen plattformunabhängige Bibliothek für grafische Oberflächen schwer umsetzbar unterschiedliches Verhalten von Benutzerschnittstellen auf den Plattformen (Menüs, Scrollbars, etc.) 4 / 56 SWING Literatur Vor- und Nachteile AWT Oberfläche verhält sich so wie erwartet entspricht optisch den nativen Programmen der Plattform Programme zeigen merkwürdige Seiteneffekte durch Unabhängigkeit nur wenige Widgets verfügbar für modernere, anspruchsvollere grafische Oberflächen ungeeignet heavyweight components beziehen Ressourcen von der nativen Plattform 5 / 56 SWING Literatur JFC Netscape entwickelte Erweiterungen Internet Foundation Classes IFC 1997 einigten sich IBM Netscape und Sun auf eine GUI-Bibliothek die auf die IFC aufbaut Java Foundation Classes JFC 6 / 56 SWING Literatur JFC Bestandteile SWING-GUI-Komponenten mit vielen neuen grafischen Elementen SWING ist kein Ersatz - benutzt Teile aus der AWT-Architektur (Frame → JFrame) Pluggable Look and Feel Aussehen der Komponenten kann zur Laufzeit geändert werden Java 2D-API ermöglicht komplexere Objekte zu bilden Drag’n Drop ermöglicht Datenübertragung zwischen Applikationen Unterstützung für Menschen mit Behinderungen 7 / 56 SWING Literatur SWING Eigenschaften mehr Komponenten Labels auf den Schaltflächen Komponenten können transparent und geformt sein und einen Rahmen haben SWING-Methoden sind nicht Thread-sicher. Parallelität kann probleme erzeugen 9 / 56 SWING Literatur Einen Frame erzeugen JFrame abgeleitet von der AWT-Klasse Frame Paket javax.swing Fenster (Toplevel-Container) erzeugen (Fenster ist in keinem anderen enthalten) Fensterdekorationen ( Titel, Buttons etc. ) werden vom Fenstersystem beeinflusst und nicht von SWING 11 / 56 SWING Literatur Beispiel JFrame hat eine default Größe von 0 x 0 Pixeln setDefaultCloseOperation() gibt Verhalten beim Schließen des Fensters an (Applikation beenden oder Fenster in den Hintergrund) erst setVisible(true) macht Fenster sichtbar dadurch können vorher Komponenten hinzugefügt werden 12 / 56 SWING Literatur Beispiel package examples ; import javax . swing . JFrame ; public class JFrameTest { public static void main ( String [] args ) { JFrame frame = new JFrame ( " Hello World " ); frame . s e t D e f a u lt C l o se O p e ra t i o n ( JFrame . EXIT_ON_CLOSE ); frame . setSize ( 300 , 100 ); frame . setVisible ( true ); } } 13 / 56 SWING Literatur Positionierung von Frames setLocation und setBounds setzen Position setIconIamge setz das Icon in der Taskleiste etc. setTitle Titel des Fensters setResizeable Größe veränderbar? mit der Klasse Toolkit abstrahiert von system- und bildschirmabhängigen Implementierungen, für jede Plattform eine Implementierung (WToolkit Windows ermöglicht Herausfinden der Bildschirmgröße etc. 14 / 56 SWING Literatur Struktur von JFrame JFrame besitzt nur einen Container JRootPane dieser verwaltet eine Layered-Pane die ein Menü und die Content-Pane aufnimmt Glass-Pane als Glasscheibe über allen Komponenten der Container von JFrame der die Komponenten aufnimmt heisst Content-Pane Komponenten werden mit der Funktion add() hinzugefügt da der JFrame mehrere Container verwaltet musste man vor Java 5 zurerst den Content-Pane erfragen: Container cont = frame . getContentPane (); cont . add ( component ); 15 / 56 SWING Literatur atomare Komponenten Komponenten die direkt angezeigt werden und selber kein Container sind atomare Komponenten JLabel javax.swing.JLabel wird mit add() hinzugefügt JLabel löst keine Events aus ist aber Component und reagiert z.B. auf MausOperationen 17 / 56 SWING Literatur Beispiel public class JLabelTest { public static void main ( String [] args ) { JFrame frame = new JFrame (); frame . s e t D e f a u lt C l o se O p e ra t i o n ( JFrame . EXIT_ON_CLOSE ); JLabel label = new JLabel ( " neues Label " ); label . setForeground ( Color . MAGENTA ); frame . add ( label ); frame . pack (); frame . setVisible ( true ); } } 18 / 56 SWING Literatur Events ausgesendete Botschaften werden in Ereignisklassen eingeteilt Ereignisse sind Objekte die aus einer Unterklasse von AWTEvent gebildet sind AWTEvent befindet sich direkt in java.awt Ereignissklassen selber in java.awt.event jede Ereignisklasse besitzt eine ID die mit getID() erfragt werden kann 19 / 56 SWING Literatur Event-Listener es existieren Ereignis-Auslöser wie Schaltflächen es gibt eine Reihe von Interessenten die informiert werden wollen Interessent ist nur an bestimmten Ereignissen interessiert muss sich bei der Ereignisquelle anmelden für jedes Ereignis gibt es einen eigenen Listener, an den das Ereignis weitergeleitet wird z.B. ActionListener, MouseListener 21 / 56 class WithoutAdapter extends JFrame implements WindowListener { public void windowClosing ( WindowEvent event ) { System . exit ( 0 ); } public void windowClosed ( WindowEvent event ) { } public void win dowDeiconified ( WindowEvent event ) public void windowIconified ( WindowEvent event ) { public void windowActivated ( WindowEvent event ) { public void win dowDeactivated ( WindowEvent event ) public void windowOpened ( WindowEvent event ) { } WithoutAdapter (){ setSize ( 400 , 400 ); addW indowL istener ( this ); setVisible ( true ); } public static void main ( String [] args ) { new WithoutAdapter (); } } { } } } { } SWING Literatur Listener hinzufügen addEreignis Listener removeEreignis Listener für Fenster z.B. addWindowListener Adapterklassen für Listener (nicht mehr jede Methode muss implementiert werden) Adapterklasse für Schnittstelle WindowListener heisst WindowAdapter man überschreibt nur noch die Methode die man braucht 23 / 56 SWING Literatur Listener mit Adapterklasse public class WithAdapter { public static void main ( String [] args ) { JFrame frame = new JFrame (); frame . setSize ( 400 , 400 ); frame . setVisible ( true ); frame . addWin dowListener ( new CloseWindowAction () ); } } class CloseW indowAction extends WindowAdapter { public void windowClosing ( WindowEvent e ) { System . exit (0); } } 24 / 56 SWING Literatur Listener mit innerer anonymer Klasse public class Inner extends JFrame { public Inner () { setSize ( 100 , 100 ); addW indowL istener ( new WindowAdapter () { public void windowClosing ( WindowEvent e ) { System . exit ( 0 ); } } ); } public static void main ( String [] args ) { new Inner (). setVisible ( true ); } } 25 / 56 SWING Literatur Schaltflächen Schaltflächen oder Buttons ermöglichen Interaktion JButton reagiert auf Aktivierung und erzeugt ein ActionEvent das ein ActionListener meldet JButton leitet von der Oberklasse AbstractButton ab ebenso JToggleButton und JMenuItem gemeinsame Eigenschaften: Selbstauslösung doClick(), Icons setDisabledIcon(Icon), setPressedIcon(Icon) etc. Ausrichtung von Text und Position von Text und Icons 26 / 56 SWING Literatur Beispiel public class JButtonTest { public static void main ( String [] args ) { JFrame frame = new JFrame (); frame . s e t D e f a u lt C l o se O p e ra t i o n ( JFrame . EXIT_ON_CLOSE ); final Icon icon1 = new ImageIcon ( JButtonTest . class . getR final JButton testButton = new JButton ( icon1 ); frame . add ( testButton ); frame . pack (); frame . setVisible ( true ); } } 27 / 56 SWING Literatur Actions eine Aktion löst ein Event aus - mehrere Möglichkeiten (Shortcut, Menu etc.) javax.swing.Action Unterschiedliche Aktionen definierbar Unterklassen von AbstractAction nutzen und ActionPerformed() überschreiben Action exitAction = new AbstractAction ( " Quit " ) { public void actionPerformed ( ActionEvent e ) { System . exit ( 0 ); } }; JButton but = new JButton ( exitAction ); frame . add ( but ); 28 / 56 SWING Literatur Component und JComponent Component ist die Basisklasse der Komponenten JComponent ist erweiterte Klasse allerdings leitet sie nicht direkt ab sondern erst von Container und dann jede JComponent ist auch ein Container JComponent bietet viele Funktionen für Tooltips, Rahmen, Tastaturbedienung 29 / 56 SWING Literatur Component und JComponent Events Component Container JComponent ComponentEvent FocusEvent KeyEvent MouseEvent InputMethodEvent HierachyEvent PropertyChangedEvent ContainerEvent PropertyChangeEvent AncestorEvent 30 / 56 SWING Literatur Component-Listener ComponentListener ist Basisklasse für alle Komponenten die Ereignisse empfangen componentHide( ComponentEvent e ) Komponente wurde versteckt componentMoved( ComponentEvent e ) Komponente wurde bewegt componentResized( ComponentEvent e ) Größe der Komponente wurde verändert componentShown( ComponentEvent e ) Komponente wurde angezeigt Tastaturbedienung 32 / 56 SWING Literatur Container Komponenten müssen auf einem Container platziert werden Container nehmen Kinder auf und verwalten diese JPanel ist im JComponent mit der Möglichkeit die Kinder anzuordnen JScrollPane Komponente mit Scrollbalken JTabbedPane mit Reitern JSplitPane Darstellung von zwei Komponenten Tastaturbedienung 33 / 56 SWING Literatur Beispiel public class Tab { public static void main ( String [] args ) { JFrame frame = new JFrame (); frame . s e t D e f a u lt C l o se O p e ra t i o n ( JFrame . EXIT_ON_CLOSE ); JTabbedPane tab = new JTabbedPane (); tab . addTab ( " Tab 1 " , new JButton ( " Tab 1 " ) ); tab . addTab ( " Tab 2 " , new JTextArea () ); frame . add ( tab ); frame . pack (); frame . setVisible ( true ); } } 36 / 56 SWING Literatur Rollbalken JScrollBar durch verschieben eines Knopfes lässt sich ein Wert auswählen wählt ganzzahligen Wert aus vorher definierten Werten aus bei vertikalem Balken liegt der größte Wert oben bei horizontalen links die wichtigsten Werte sind Orientierung (vertikal, horizontal), Minimal-, Maximalwert, aktueller Wert für Events muss AdjustmentListener implementiert werden adjustmentValueChanged( AdjustmentEvent e ) wird vom Rollbalken aufgerufen 37 / 56 SWING Literatur Schieberegler JScrollBar ähnlich wie Rollbalken Auswahl eines Wertes zusätzlich kann die Skala durch Striche dargestellt werden die ticks können auch automatisch nummeriert werden auf Events hört der ChangeListener 38 / 56 SWING Literatur Layout Manager ein Layout Manager ordnet die Elemente eines Containers Container fragt bei der Darstellung den Layoutmanager wie die Elemente dargstellt werden sollen Layoutmanager in Java: FlowLayout von links nach rechts BoxLayou horizontal oder vertikal GridLayout Raster mit gleichgroßen Elementen BorderLayout in vier Himmelsrichtungen oder Mitte GridBagLayout Erweiterung von GridLayout CardLayout verwaltet Komponenten wie einen Stapel (nur eine sichtbar) SpringLayout Berücksichtigt Kanten von Komponenten GroupLayout der Layout-Manager wird einem Container mit setLayout (LayoutManager) zugewiesen 39 / 56 Border Layout Box Layout FlowLayout SWING Literatur Kontrollfelder Kontrollfeler haben einen Zustand an oder aus JCheckBox kann mit Grafiken den Zustand darstellen auf Events hört der ItemListener mit getState() und setState() kann Zustand erfragt bzw. geändert werden 41 / 56 public static void main ( String [] args ) { JFrame frame = new JFrame ( " Frame " ); frame . s e t D e f a u lt C l o se O p e ra t i o n ( JFrame . EXIT_ON_CLOSE ); Icon unchecked = new ImageIcon ( Check . class . getResource ( Icon checked = new ImageIcon ( Check . class . getResource ( JCheckBox box = new JCheckBox ( " Checkbox " , true ); box . setIcon ( unchecked ); box . setSelectedIcon ( checked ); frame . add ( box , BorderLayout . PAGE_START ); ItemListener boxListener = new ItemListener () { public void itemStateChanged ( ItemEvent e ) { System . out . print ( (( JCheckBox ) e . getItem ()). getText ( } }; box . addItemListener ( boxListener ); frame . pack (); frame . setVisible ( true ); } SWING Literatur Fortschrittsbalken JProgressBar zeigt das Vorankommen (oder Nichtvorankommen) einer Anwendung die wichtigsten Werte sind Orientierung (vertikal, horizontal), Minimal-, Maximalwert, aktueller Wert setValue(int n) setz den Wert 43 / 56 SWING Literatur Menüs Fenstermenüs und Popup-Menüs sind immer mit einem Fenster verbunden Menübalken nimmt Menüeinträge auf sitzt auf einem Toplevel-Container außerhalb der Content-Pane Menüeintrage lösen Aktionen aus und können weitere Einträge enthalten (Untermenü) 44 / 56 SWING Literatur Menüs JMenu JMenuBar() erzeugt einen neuen Menübalken setJMenuBar(JMenubar menubar) weist Menü einem JFrame zu JMenu(String s) erzeugt ein neues Menü JMenu add(JMenu c) fügt neue Menüzeile JMenuBar menuBar = new JMenuBar (); JMenu fileMenu = new JMenu ( " Datei " ); menuBar . add ( fileMenu ); f . setJMenuBar ( menuBar ); 45 / 56 SWING Literatur Menüeinträge JMenuItem add() fügt die vertikalen Elemente vom Typ JMenuItem hinzu JMenuItem JMenu als Unterklasse für Untermenüs addSeparator() fügt Trennlinie ein Menüeinträge lassen sich mit Action-Objekten belegen JMenu helpMenu = new JMenu ( " Hilfe " ); menuBar . add ( helpMenu ); helpMenu . add ( new JMenuItem ( " Programm " ) ); 46 / 56 SWING Literatur Popup-Menüs haben keine feste Position meistens auf Rechtsklick des Benutzers aktiviert (Kontextmenü) JPopupMenu analog wie JMenu zum Öffnen auf Mausereignis hören und show() aufrufen 47 / 56 SWING Literatur Texteingabefelder vershiedene Möglichkeiten in SWING JTextField einzeiliges Eingabefeld JFormattedTextField einzeiliges Textfeld mit Formatierungsvorgaben JPasswordField verdeckte Eingabe JTextArea mehrzeilig JEditorPane Editor JTextPane spezieller Editor alle von JTextComponent abgeleitet wichtige Methoden setText(String) und getText() 48 / 56 SWING Literatur Formatiertes Eingabefeld JFormat t e dT e x tF i e ld ftf1 = new JFormattedTextField ( new SimpleDateFormat ( " MM / dd / yy " ) ); 49 / 56 SWING Literatur Tabellen JTable zweidimensionale Tabellen bei Bedarf auch eigenes Tabellenmodell als Eingabe ein zweidimensionales Feld String [][] data = { { " A " , " B " } , { " U " , " V " } }; JTable table = new JTable ( data ); 50 / 56 SWING Literatur Tabellen-Modell Trennung von Daten und Anzeige Daten werden durch die Schnittstelle TableModel um auf die Daten einer Tabelle zugreifen zu können braucht man das Modell auch eigenes Modell möglich das mit setModel(TableModel) gesetzt werden kann 51 / 56 SWING Literatur Dialoge und Windows JFrame Fenster mit Dekoration java.awt.Window nicht Swing-Unterklasse JWindow Dialoge java.awt.Dialog und JDialog Dialoge können modal oder nicht-modal sein (bei modal Rest solange gesperrt bis Nutzer reagiert) Meldedialoge, Eingabedialoge, Bestätigungsdialoge etc. mit JOptionPane können einfach durch entsprechenden Aufruf verwendet werde showXXXDialog() 52 / 56 JOptionPane . showInputDialog ( " Bitte Name eingeben " ); JOptionPane . show ConfirmDialog ( null , " Alles OK ? " ); JOptionPane . show MessageDialog ( null , " Message " ); String [] optionen = { " Ja " , " Nein " , " Abbrechen " }; int n = JOptionPane . showOptionDialog ( null , " Ja oder Nein ? " , // Fragetext " Ja / Nein / Abbrechen " , // Titel JOptionPane . YES_NO_CANCEL_OPTION , JOptionPane . QUESTION_MESSAGE , // Icon null , optionen , optionen [0] ); if ( n == JOptionPane . YES_OPTION ) System . out . println ( " Ja " ); SWING Literatur Dateiauswahl JFileChooser zur Auswahl von Dateien und Verzeichnissen ist modal und kann fürs Öffnen oder fürs Speichern konfiguriert sein erst nach Schließen mit der OK Schaltfläche können die Datein verwendet werden Filtern nach bestimmten Dateien ist möglich Erzeugen mit JFileChooser() ausgewählte Datei oder Verzeichnis abfragbar durch getSelectedFile() und getDirectory() FileFilter muss die Methoden accept() und getDescription() implementieren 54 / 56 SWING Literatur Nebenläufgkeit Ereignisse gelangen in eine Ereigniswarteschlange event queue jedes Fenster hat eine eigene Event-Queue AWT-Event-Thread läuft parallel und arbeitet die Ereignisse ab führt auch den Prorgammcode in den Listenern aus dauert die Abarbeiten in dem Handler lange steht das Programm Swing ist nicht Thread-sicher bei konkurrierenden Zugriffen gibts eine Exception deshalb Methoden zur um die Aufträge in den AWT-Thread einzureihen invokeLater(Runnable) und invokeAndWait(Runnable) 55 / 56 SWING Literatur Christian Ullenboom. Java ist auch eine Insel. Galileo Computing, 7 edition, 2008. ISBN 978-3-8362-1146-8. 56 / 56