© 2009 – 2014, Prof. Dr. D. Ratz 16 Zeichnen in Swing-Komponenten © 2009 – 2014, Prof. Dr. D. Ratz 16.1 Grafische Darstellung von Komponenten • Der Repaint-Manager sorgt für die grafische Darstellung der Komponenten – Aktivierung beim erstmaligen Erscheinen – Aktualisierung bei Änderungen der Gestalt • Alle Methoden, die Komponenten verändern können, rufen dazu die Methode – public void repaint() aus der Klasse Component auf. • • Dadurch wird der Repaint-Manager veranlasst, die Komponente durch einen Aufruf ihrer Methode – public void paint(Graphics g) neu zu zeichnen. Die Methode paint ruft zu diesem Zweck die Instanzmethoden – protected void paintComponent(Graphics g) – protected void paintBorder(Graphics g) – protected void paintChildren(Graphics g) (in dieser Reihenfolge) auf, wodurch die Komponente selbst, ihr Border-Bereich und alle in die Komponente bereits eingefügten Komponenten gezeichnet werden. 16 - 1 © 2009 – 2014, Prof. Dr. D. Ratz Grafische Darstellung von Komponenten • • • Zur Veränderung der grafischen Darstellung einer Komponente kann die Methode paintComponent angepasst (überschrieben) werden. Durch einen Aufruf repaint() kann jederzeit auch explizit ein nochmaliges Zeichnen einer Komponente angestoßen werden. Die paint-Methoden haben einen Parameter g vom Typ Graphics: – stellt den Bezug zum grafischen Kontext, also zum tatsächlichen Ausgabegerät, auf dem die Komponente gezeichnet wird, her • – stellt zahlreiche Methoden bereit, die es ermöglichen, innerhalb des Grafikkoordinatensystems einer Komponente zu zeichnen Grafikkoordinatensystem (Koordinatenangaben in Pixeln, Ursprung links oben): 0 1 0 1 5 10 15 x 5 10 y 16 - 2 © 2009 – 2014, Prof. Dr. D. Ratz 16.2 • Methoden zum Zeichnen Öffentliche Instanzmethoden von Graphics (bzw. java.awt.Graphics) – void drawLine(int x1, int y1, int x2, int y2) – void drawRect(int x, int y, int w, int h) – void drawOval(int x, int y, int w, int h) – void drawArc(int x, int y, int w, int h, int s, int a) – void drawString(String str, int x, int y) – void fillRect(int x, int y, int w, int h) – void fillOval(int x, int y, int w, int h) – ... • Beispiele – g.drawLine(1,2,1,9); 0 1 0 1 5 10 15 x 5 – g.drawRect(3,2,13,8); – g.drawOval(6,3,8,5); – g.fillArc (7,4,6,6,0,90); 10 y 16 - 3 © 2009 – 2014, Prof. Dr. D. Ratz 16.3 • Beispiel Programm, das ein Zeichenbrett bietet, auf dem Punkte markiert und automatisch durch Linien verbunden werden können public class PunkteVerbinden extends JFrame { Container c; Zeichenbrett z; public PunkteVerbinden() { c = getContentPane(); z = new Zeichenbrett(); c.add(z); } public static void main(String[] args) { PunkteVerbinden fenster = new PunkteVerbinden(); fenster.setTitle("Punkte verbinden"); fenster.setSize(250,200); fenster.setVisible(true); fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } 16 - 4 } © 2009 – 2014, Prof. Dr. D. Ratz Beispiel public class Zeichenbrett extends JPanel { private int[] x, y; // Koordinaten der Maus-Klicks private int n; // Anzahl Klicks public Zeichenbrett() { n = 0; x = new int[1000]; y = new int[1000]; addMouseListener(new ClickBearbeiter()); } // paintComponent ueberschreiben public void paintComponent(Graphics g) { g.drawPolyline(x,y,n); // alle Koordinaten verbinden } 16 - 5 © 2009 – 2014, Prof. Dr. D. Ratz Beispiel // Innere Listener-Klasse fuer Maus-Ereignisse class ClickBearbeiter extends MouseAdapter { public void mousePressed(MouseEvent e) { x[n] = e.getX(); // speichere x-Koordinate y[n] = e.getY(); // speichere y-Koordinate n++; // erhoehe Anzahl Klicks repaint(); // Neuzeichnen der Komponente beim // Repaint-Manager anfordern } } } 16 - 6 © 2009 – 2014, Prof. Dr. D. Ratz 16.4 Komponenten hinzufügen: repaint vs. revalidate • Beispiel für ereignisgesteuertes Hinzufügen von Komponenten public class NewButtonFrame1 extends JFrame { Container c; JButton b; public NewButtonFrame1() { c = getContentPane(); c.setLayout(new FlowLayout(FlowLayout.LEFT)); b = new JButton("Drueck mich!"); b.addActionListener(new ButtonBearbeiter()); c.add(b); } class ButtonBearbeiter implements ActionListener { public void actionPerformed(ActionEvent e) { c.add(new JButton("noch einer")); c.repaint(); } } "Resize-Click" 16 - 7 © 2009 – 2014, Prof. Dr. D. Ratz Komponenten hinzufügen: repaint vs. revalidate • Korrekte Variante für ereignisgesteuertes Hinzufügen von Komponenten public class NewButtonFrame2 extends JFrame { Container c; JButton b; public NewButtonFrame2() { c = getContentPane(); c.setLayout(new FlowLayout(FlowLayout.LEFT)); b = new JButton("Drueck mich!"); b.addActionListener(new ButtonBearbeiter()); c.add(b); } class ButtonBearbeiter implements ActionListener { public void actionPerformed(ActionEvent e) { c.add(b = new JButton("noch einer")); b.revalidate(); } Die komplette Container} Hierarchie wird revalidiert! 16 - 8 © 2009 – 2014, Prof. Dr. D. Ratz 16.5 • Anpassen des Look and Feel Zur Laufzeit eines Programms String[] laf = {"javax.swing.plaf.metal.MetalLookAndFeel", "com.sun.java.swing.plaf.motif.MotifLookAndFeel", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel", "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel"}; int i = ...; UIManager.setLookAndFeel(laf[i]); SwingUtilities.updateComponentTreeUI(f); • Beim Programmstart java -Dswing.defaultlaf=javax.swing.plaf.metal.MetalLookAndFeel ProgName 16 - 9