Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 7. Auflage |
<< | < | > | >> | API | Kapitel 38 - Swing: Komponenten I |
Seit der Version 7 des JDK gibt es im Paket javax.swing die Klasse JLayer. Sie dient dazu, Swing-Komponenten zu »dekorieren«, d.h. um Eigenschaften zu erweitern, ohne sich von der Komponente selbst ableiten zu müssen (entsprechend dem Design-Pattern »Dekorator«). Mit ihrer Hilfe können das Aussehen und die Ereignisbehandlung von Dialogelementen verändert werden.
Mit einem JLayer lassen sich ähnliche Effekte erzielen wie mit einer GlassPane, auf die wir bereits in Abschnitt 37.1.1 eingegangen sind. Einfach gesprochen handelt es sich bei einem JLayer um eine transparente View, die über der dekorierten Komponente liegt. Das lässt sich z.B. dazu verwenden, um bei einem langlaufenden Hintergrundprozess Teile der grafischen Oberfläche durch optische Effekte zu sperren. Bei der Implementation kann man dann klar zwischen den Funktionen der dekorierten Komponente und den Effekten des JLayer trennen, was die Lesbar- und Wartbarkeit des Codes erhöht.
Die Klasse JLayer delegiert an ihre UI-Klasse LayerUI. Deren wichtigste Methoden sind:
public void paint(Graphics g, JComponent c) public void installUI(JComponent c) public void uninstallUI(JComponent c) |
javax.swing.plaf.LayerUI |
Da sich die Klasse JLayer von JComponent (siehe Abschnitt 37.3.1) ableitet, erbt sie deren add-Methoden. Diese können jedoch nicht verwendet werden, sondern man übergibt die zu dekorierende Komponente über den Konstruktor an das JLayer-Objekt. JLayer und LayerUI sind generische Klassen, sie erwarten den Typ V der dekorierten Komponente.
public JLayer(V view, LayerUI<V> ui) public JLayer(V view) public void setLayerEventMask(long layerEventMask) public void setUI(LayerUI<? super V> ui) |
javax.swing.JLayer |
Am einfachsten erklärt sich die Funktionsweise anhand eines Beispiels. Das folgende Listing dekoriert dazu ein JPanel, auf dem wir eine Reihe von JLabel-Objekten platzieren. Wenn auf das Panel mit der Maus geklickt wird, soll um den Punkt herum ein kleiner blauer Kreis gezeichnet werden.
Wir merken uns dazu in einer Liste die Mausklickpositionen und überschreiben die paint-Methode der LayerUI-Klasse. Mit drawOval zeichnen wir die blauen Kreise. Um die Mausereignisse zu empfangen, müssen wir uns mit der Methode setLayerEventMask der Klasse JLayer für Mausereignisse registrieren. Alle Mausereignisse, die das dekorierte Panel oder eines seiner Subkomponenten empfängt, erhält nach der Registrierung auch der LayerUI.
Die Methoden installUI und uninstallUI sind Callback-Methoden, mit denen wir das Registrieren und Deregistrieren vornehmen können.
001 /* Listing3815.java */ 002 003 import java.awt.*; 004 import java.awt.event.MouseEvent; 005 import java.util.*; 006 import java.util.List; 007 008 import javax.swing.*; 009 import javax.swing.plaf.LayerUI; 010 011 public class Listing3815 extends JFrame 012 { 013 private final static int RADIUS = 10; 014 private final List<Point> points = new ArrayList<Point>(); 015 016 public Listing3815() 017 { 018 super("JLayer"); 019 addWindowListener(new WindowClosingAdapter(true)); 020 021 LayerUI<JPanel> ui = new LayerUI<JPanel>() 022 { 023 public void paint(Graphics g, JComponent c) 024 { 025 super.paint(g, c); 026 g.setColor(Color.BLUE); 027 for (Point p : points) { 028 g.drawOval(p.x-RADIUS, p.y-RADIUS, 2*RADIUS, 2*RADIUS); 029 } 030 } 031 032 protected void processMouseEvent(MouseEvent e, JLayer<? extends JPanel> l) 033 { 034 super.processMouseEvent(e, l); 035 if (e.getID() == MouseEvent.MOUSE_CLICKED) { 036 points.add(e.getPoint()); 037 } 038 l.repaint(); 039 } 040 041 public void installUI(JComponent c) 042 { 043 super.installUI(c); 044 ((JLayer<?>) c).setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK); 045 } 046 047 public void uninstallUI(JComponent c) 048 { 049 super.uninstallUI(c); 050 ((JLayer<?>) c).setLayerEventMask(0); 051 } 052 }; 053 054 final JPanel panel = new JPanel(new FlowLayout()); 055 for (int i = 0; i < 20; i++) { 056 JLabel label = new JLabel("Label "+ i); 057 panel.add(label); 058 } 059 060 Container cp = getContentPane(); 061 cp.add(new JLayer<JPanel>(panel, ui), BorderLayout.CENTER); 062 } 063 064 public static void main(String[] args) 065 { 066 Listing3815 frame = new Listing3815(); 067 frame.setLocation(100, 100); 068 frame.setSize(250, 200); 069 frame.setVisible(true); 070 } 071 } |
Listing3815.java |
Das folgende Bild zeigt die Beispielanwendung unter Ubuntu:
Abbildung 38.13: Die Klasse JLayer
Titel | Inhalt | Suchen | Index | DOC | Handbuch der Java-Programmierung, 7. Auflage, Addison Wesley, Version 7.0 |
<< | < | > | >> | API | © 1998, 2011 Guido Krüger & Heiko Hansen, http://www.javabuch.de |