Titel   Inhalt   Suchen   Index   DOC  Handbuch der Java-Programmierung, 7. Auflage
 <<    <     >    >>   API  Kapitel 38 - Swing: Komponenten I

38.5 JLayer



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
Listing 38.15: Die Klasse JLayer

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