Thema der Woche: Besondere Methoden der Renderer

Der “Bug” http://bugs.sun.com/view_bug.do?bug_id=4706356 führte zu einer Änderung, die http://docs.oracle.com/javase/7/docs/technotes/guides/swing/1.5/index.html so beschreibt:

Swing’s cell rendenders override a handful of methods to do nothing as they are not needed for cell renderers. They should override a couple of methods that are now being called to do nothing.

The following methods were added to DefaultTableCellRenderer, DefaultListCellRenderer and DefaultTreeCellRenderer

    /**
     * Overridden for performance reasons.
     * See the <a href="#override">Implementation Note</a>
     * for more information.
     *
     * @since 1.5
     */
    public void invalidate();
    /**
     * Overridden for performance reasons.
     * See the <a href="#override">Implementation Note</a>
     * for more information.
     *
     * @since 1.5
     */
    public void repaint();

Erkläre die Arbeitsweise und warum die Methoden überschrieben wurden. (Ist das Listing oben überhaupt korrekt?) Wie sieht das bei Komponenten bei SwingX aus?

Ähnliche Beiträge

2 Gedanken zu “Thema der Woche: Besondere Methoden der Renderer

  1. Die DefaultTableCellRenderer, DefaultListCellRenderer und DefaultTreeCellRenderer erben von JLabel, aber nutzen nur die Property Fähigkeiten um Icons und den Text einer Zelle zu setzen. Die Renderer geben ein Component Objekt zurück auf dem letzten Endes die paint(Graphic) Methode aufgerufen wird um die Zelle zu zeichnen.

    DefaultTableCellRenderer – getTableCellRendererComponent(…)
    DefaultListCellRenderer – getListCellRendererComponent(…)
    DefaultTreeCellRenderer – getTreeCellRendererComponent(…)

    Danach wird dieses Component Objekt allerdings von der JTable/JList/JTree nicht mehr benötigt. Es fungiert nur als „Zeichner“ für den aktuellen Zustand der Zelle.

    Die Default…Renderer benutzen nun immer ein und das selbe Component Objekt. Sich selbst genau genommen. Damit nicht immer ein neues Component Objekt erzeugt werden muss, da die Renderer wegen jedem kleinen bisschen aufgerufen werden. Selbst, wenn man nur mit dem Mauszeiger über eine Zelle fährt. Es ändern sich also nur die Properties.

    Allerdings das setzen eines Textes über die setText(String) Methode des JLabels triggert ein repaint() und revalidate(). Diese Methoden reichen ihren Aufruf bis zu ihrer Parent Componente weiter und dann wird die paint(Graphic) Methode aufgerufen. D.h. wenn man diese Methoden nicht überschrieben hätte, dann würde man sehr oft etwas zeichnen was man nicht sieht, da diese JLabel Objekte (also die Default…Renderer) keinem Container zu geordnet sind. Und das jedes mal, wenn man eine Property ändert.

    Gleiches gilt auch für die validate, revalidate, firePropertyChange und isOpaque Methoden des JLabels und deswegen sind sie alle in den Default…Renderern überschrieben um nichts zu tun.

    Endlich mal eine Frage, die ich ausm FF beantworten konnte. 😀

  2. Und noch kurz zu den SwingX Klassen:

    SwingX benutzt eine eigene API für Renderer. Diese sind umfangreicher an Funktionen und Klassen. Sehr verschachtelt (das muss man wirklich mal sagen). Deren Renderer

    DefaultListRenderer
    DefaultTableRenderer
    DefaultTreeRenderer

    delegieren alle an ein ComponentProvider. Dieser enthält die Renderer Componente. Der ComponentProvider und seine Componente wird bei der Erzeugung des Default…Renderer erzeugt bzw. gesetzt. Ist also auch einmalig, aber basiert nicht auf Vererbung. Es gibt CheckBoxProvider, HyperlinkProvider, LabelProvider und WrappingProvider. Zu jedem dieser Provider gibt es eine spezielle JComponent, die nur für die Renderer gedacht sind:

    CheckBoxProvider – JRendererCheckBox
    HyperlinkProvider – JXRendererHyperlink
    LabelProvider – JRendererLabel
    WrappingProvider – WrappingIconPanel

    Und genau diese speziellen JComponent Klassen überschreiben invalidate, validate, revalidate, repaint usw.

    Fazit: Also das Gleiche wie in den normalen Default…Renderer von Swing. Nur anders aufgebaut. 🙂

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert