11. GUI-Programmierung mit SWING Überblick 11.1 11.2 11.3 11.4 11.5 11.6 11.7 Einführung Einfache Swing Komponenten Ereignisbehandlung und Adapterklassen Zeichnen Dialoge Layout Manager Komplexere Swing Komponenten © Prof. Dr. Björn Dreher Liste Programmieren - Java 548 11. GUI-Programmierung mit SWING Überblick: 11.4. Zeichnen 11.4.1 Der Java graphische Context 11.4.2 11.4.3 Subklasse von JPanel Anwendung © Prof. Dr. Björn Dreher Liste Programmieren - Java 549 1 11. SWING: 11.4. Zeichnen 11.4.1 Der Java graphische Kontext Basis Klassen für 2D-Darstellungen Graphics Color Font FontMetrics Polygon Java2D API BasicStroke GradientPaint TexturePaint GeneralPath Arc2D, Ellipse2D, Line2D, Rectangle2D, RoundRectangle2D © Prof. Dr. Björn Dreher Liste Programmieren - Java 550 11. SWING: 11.4. Zeichnen 11.4.1 Der Java graphische Kontext Koordinatensystem +x (0, 0) x-Achse (x, y) +y y-Achse Ausgangspunkt: Linke obere Ecke Einheit: Pixel © Prof. Dr. Björn Dreher Liste Programmieren - Java 551 2 11. SWING: 11.4. Zeichnen 11.4.1 Der Java graphische Kontext Graphischer Kontext Graphics Objekt Methoden zum Zeichnen Font-Manipulation Farbwahl, usw. Zum Zeichnen wird oft die Methode paint(Graphics g) aufgerufen paint() kann überschrieben werden Im Innern kann dann g zum Zeichnen benutzt werden Wird normalerweise indirekt über repaint() aufgerufen Graphics ist eine abstrakte Klasse Konkrete Klasse realisiert die Schnittstelle für die Zielplattform (Windows, Unix, Mac) Bei Swing ist es tatsächlich eine Instanz von Graphics2D Unterstützt zusätzlich 2D-API, Nachfahre von Graphics © Prof. Dr. Björn Dreher Liste Programmieren - Java 552 11. GUI-Programmierung mit SWING Überblick: 11.4. Zeichnen 11.4.1 Der Java graphische Context 11.4.2 Subklasse von JPanel 11.4.3 Anwendung © Prof. Dr. Björn Dreher Liste Programmieren - Java 553 3 11. SWING: 11.4. Zeichnen 11.4.2 Subklasse von JPanel JPanel Normalerweise ein Aggregat für andere Swing Komponenten Kann auch Zeichenoberflächen und mausempfindliche Bereiche definieren Vermeidung von Konflikten zwischen direkter Verwendung von Graphics und GUI-Komponenten Methode paint() Nur von der Swing-Laufzeitumgebung aufgerufen, niemals direkt aus Benutzercode Stattdessen repaint() © Prof. Dr. Björn Dreher Bittet Swing, die Komponente bei nächster Gelegenheit sich zeichnen zu lassen Liste Programmieren - Java 554 11. SWING: 11.4. Zeichnen 11.4.2 Subklasse von JPanel JPanel Methode paint() (fortgesetzt) Zeichnet die Komponente selbst und alle darin enthaltenen Unterkomponenten Delegiert den paint()-Aufruf an diese weiter Überschreibt man paint(), muss man unbedingt zuerst die geerbte Methode aufrufen Klassen, die von JComponent abstammen, enthalten Methode paintComponent() Zeichnet nur die eigene Komponente Man muss sich um enthaltene Komponemten nicht kümmern Diese Methode sollte überschrieben werden, um innerhalb des Panels zu zeichnen Zuvor sollte die geerbte Methode aufgerufen werden © Prof. Dr. Björn Dreher Liste Programmieren - Java 555 4 11. SWING: 11.4. Zeichnen 11.4.2 Subklasse von JPanel JPanel JComponent unterstützt Transparenz und deren Nachfahren sollten das auch tun Gesteuert durch Methode setOpaque() Parameter false: Komponente ist transparent Richtige Handhabung in JComponent‘s Methode paintComponent() Transparent: Hintergrund bleibt unverändert Opaque: Hintergrund wird gelöscht Daher muss geerbtes paintComponent() unbedingt aufgerufen werden © Prof. Dr. Björn Dreher Liste Programmieren - Java 556 11. SWING: 11.4. Zeichnen 11.4.2 Subklasse von JPanel Wann wird Komponente neu gezeichnet? Swing-Komponenten Methode repaint(): Komponente soll sobald wie möglich neu gezeichnet werden: Drei einzelne Methoden (in dieser Reihenfolge): paintComponent – Hauptmethode zum Zeichnen paintBorder – Zeichnet die Umrandung (falls es eine gibt). Nicht überschreiben! paintChildren – Veranlasst jede Komponente, die in der eigenen enthalten ist, sich selbst zu zeichnen. Nicht überschreiben! AWT-Komponenten Methode repaint() © Prof. Dr. Björn Dreher Methode update() von Component wird aufgerufen Löscht Hintergrund der Komponente Ruft ihrerseits Methode paint() Liste Programmieren - Java 557 5 11. SWING: 11.4. Zeichnen 11.4.2 Subklasse von JPanel CustomPanel public class CustomPanel extends JPanel { public final static int CIRCLE = 1, SQUARE = 2; private int shape; // use shape to draw an oval or rectangle public void paintComponent( Graphics g ) { super.paintComponent( g ); if ( shape == CIRCLE ) g.fillOval( 50, 10, 60, 60 ); else if ( shape == SQUARE ) g.fillRect( 50, 10, 60, 60 ); } } // set shape value and repaint CustomPanel public void draw( int shapeToDraw ) { shape = shapeToDraw; repaint(); } // end class CustomPanel © Prof. Dr. Björn Dreher Liste Programmieren - Java 558 11. GUI-Programmierung mit SWING Überblick: 11.4. Zeichnen 11.4.1 Der Java graphische Context 11.4.2 Subklasse von JPanel 11.4.3 Anwendung © Prof. Dr. Björn Dreher Liste Programmieren - Java 559 6 11. SWING: 11.4. Zeichnen 11.4.3 Anwendung CustomPanelTest public class CustomPanelTest extends JFrame { private JPanel buttonPanel; private CustomPanel myPanel; private JButton circleButton, squareButton; // set up GUI public CustomPanelTest() { super( "CustomPanel Test" ); // create custom drawing area myPanel = new CustomPanel(); myPanel.setBackground( Color.green ); // set up squareButton squareButton = new JButton( "Square" ); ... © Prof. Dr. Björn Dreher Liste Programmieren - Java 560 11. SWING: 11.4. Zeichnen 11.4.3 Anwendung CustomPanelTest (fortgesetzt) ... squareButton.addActionListener( // anonymous inner class to handle // squareButton events new ActionListener() { // draw a square public void actionPerformed( ActionEvent event ) { myPanel.draw( CustomPanel.SQUARE ); } } // end anonymous inner class ); // end call to addActionListener ... © Prof. Dr. Björn Dreher Liste Programmieren - Java 561 7 11. SWING: 11.4. Zeichnen 11.4.3 Anwendung CustomPanelTest (fortgesetzt) ... circleButton = new JButton( "Circle" ); circleButton.addActionListener( // anonymous inner class to handle // circleButton events new ActionListener() { // draw a circle public void actionPerformed( ActionEvent event ) { myPanel.draw( CustomPanel.CIRCLE ); } } // end anonymous inner class ); // end call to addActionListener ... © Prof. Dr. Björn Dreher Liste Programmieren - Java 562 11. SWING: 11.4. Zeichnen 11.4.3 Anwendung CustomPanelTest (fortgesetzt) ... // set up panel containing buttons buttonPanel = new JPanel(); buttonPanel.setLayout( new GridLayout( 1, 2 ) ); buttonPanel.add( circleButton ); buttonPanel.add( squareButton ); // attach button panel & custom drawing area to // content pane Container container = getContentPane(); container.add( myPanel, BorderLayout.CENTER ); container.add( buttonPanel, BorderLayout.SOUTH ); Default ist BorderLayout setSize( 300, 150 ); setVisible( true ); } ... © Prof. Dr. Björn Dreher Liste Programmieren - Java 563 8 11. SWING: 11.4. Zeichnen 11.4.3 Anwendung CustomPanelTest (fortgesetzt) ... // execute application public static void main( String args[] ) { CustomPanelTest application = new CustomPanelTest(); application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); } } // end class CustomPanelTest © Prof. Dr. Björn Dreher Liste Programmieren - Java 564 11. SWING: 11.4. Zeichnen 11.4.3 Anwendung Ergebnis © Prof. Dr. Björn Dreher Liste Programmieren - Java 565 9