Skip to content

de JComboBox Renderer

homebeaver edited this page Aug 1, 2025 · 11 revisions

Die nachfolgende Abbildung stellt die plattformübergreifende Metal L&F mit den Themen OCEAN und STEEL und andere UI-Implementierungen von JComboBox gegenüber. Die Klappliste ist in der Darstellung nicht zu sehen:

Wo findet man den Renderer für JComboBox und die Klappliste? Notfalls per Debugger.

// in JComboBox ctor wird via init() die UI angepasst:
    private void init() {
        installAncestorListener();
        setUIProperty("opaque",true);
        updateUI(); // <============
    }
    
    public void updateUI() {
    ...
            try {
                setUI((ComboBoxUI)UIManager.getUI(this));  // getUI liefert je nach Einstellung
                // MetalComboBoxUI für Metal bzw. SynthComboBoxUI für Nimbus
    ...
    }

    public void setUI(ComboBoxUI ui) {
        super.setUI(ui);  // <============ JComponent.setUI
    }

In JComponent.setUI geht es weiter je nach Umgebung (hier Metal UI):

    protected void setUI(ComponentUI newUI) {
        ...
        ui = newUI;
        if (ui != null) {
            ui.installUI(this);  // <== this=javax.swing.plaf.metal.MetalComboBoxUI
            // MetalComboBoxUI hat installUI von BasicComboBoxUI nicht überschrieben ...
        }
        ...
    }

    // also weiter in BasicComboBoxUI.installUI
    public void installUI( JComponent c ) {
        ...
        if ( comboBox.getRenderer() == null || comboBox.getRenderer() instanceof UIResource ) {
            comboBox.setRenderer( createRenderer() );  // <============ 
        }
        ...
    }

    protected ListCellRenderer<Object> createRenderer() {
        return new BasicComboBoxRenderer.UIResource(); // !!! gefunden
    }

In Nimbus UI ist es anders:

    protected void setUI(ComponentUI newUI) {
        ...
        ui = newUI;
        if (ui != null) {
            ui.installUI(this);  // <== this=javax.swing.plaf.synth.SynthComboBoxUI
        }
        ...
    }
    
    // SynthComboBoxUI.installUI :
    public void installUI(JComponent c) {
        buttonHandler = new ButtonHandler();
        super.installUI(c);
    }

    // und superclass BasicComboBoxUI.installUI
    public void installUI( JComponent c ) {
        ...
        if ( comboBox.getRenderer() == null || comboBox.getRenderer() instanceof UIResource ) {
            comboBox.setRenderer( createRenderer() );  // <============ 
        }
        ...
    }

    protected ListCellRenderer<Object> createRenderer() {
        return new SynthComboBoxRenderer();  // !!! gefunden
    }

Renderer

Der Renderer ist also je nach UI implementiert

  • in inner private class SynthComboBoxUI.SynthComboBoxRenderer extends JLabel für Nimbus (wg. private kann man den Renderer nicht so einfach erweitern) bzw.
  • in inner public static class BasicComboBoxRenderer.UIResource für Metal. Dort ist aber nichts implementiert:
    public static class UIResource extends BasicComboBoxRenderer 
                                   implements javax.swing.plaf.UIResource {
        public UIResource() {}
    }

Also ist javax.swing.plaf.basic.BasicComboBoxRenderer die default Implementierung für Metal. Und die ist nichts anderes als ein JButton mit Text und etwas Gedöns drumrum:

public class BasicComboBoxRenderer extends JLabel ... {
    protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
    public BasicComboBoxRenderer() {
        super();
        setOpaque(true);
        setBorder(getNoFocusBorder());
    }
    ...

Nimbus Renderer erweitern

Wie schon oben angedeutet, kann man den Nimbus Renderer nicht so einfach erweitern, weil er als inner private class SynthComboBoxUI.SynthComboBoxRenderer implementiert ist. Auch die createUI ist in SynthComboBoxUI. Daher erweitere ich die ganze UI-Klasse:

public class SynthYComboBoxUI extends SynthComboBoxUI {

    private static final Logger LOG = Logger.getLogger(SynthYComboBoxUI.class.getName());

    public SynthYComboBoxUI() {
        super();
    }

    // Creates a new UI object for the given component. Like in SynthComboBoxUI
    public static ComponentUI createUI(JComponent c) {
        return new SynthYComboBoxUI();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected ListCellRenderer<Object> createRenderer() {
        return new SynthYComboBoxRenderer();
    }

    // SynthComboBoxUI.SynthComboBoxRenderer is private
    @SuppressWarnings("serial") // Superclass is not serializable across versions
    public class SynthYComboBoxRenderer extends JLabel implements ListCellRenderer<Object>, UIResource {
    ...

Die UI wird in JComboBox#updateUI() gesetzt. Statt die ganze Methode zu überschreiben, genügt

public class JYComboBox<E> extends JComboBox<E> {

    private static final Logger LOG = Logger.getLogger(JYComboBox.class.getName());

    public JYComboBox(E[] items) {
        super(items);
    }

    public void setUI(ComboBoxUI ui) {
        LOG.info("ui:"+ui);
        UIDefaults uidHashtable = UIManager.getDefaults();
        uidHashtable.put("ComboBoxUI", "samples.plaf.synth.SynthYComboBoxUI");
        uidHashtable.put("ComboBox.padding", new InsetsUIResource(10, 10, 10, 10));
//        ComponentUI cui = SynthYComboBoxUI.createUI(this);
        ComponentUI cui = UIManager.getUI(this);
        if (cui instanceof ComboBoxUI cbui) {
            super.setUI(cbui);
        } else {
            super.setUI(ui);
        }
    }
...

Glossar

A

Algorithmus : eine Sammlung von Algorithmen in java, von Euklid bis RSA

AutoComplete : package bzw. class zur Autovervollständigung in Text Komponenten

B

Batik : Subprojekt von Apache XML Graphics Project

BSAF : Better Swing Application Framework

BuddySupport : erweitert Textkomponenten

C

Color : Farben im Farbkreis, Farbraum

Collection views : zu den SwingX collection views gehören JXList, JXTree, JXTable und JXTreeTable

ComboBox : allgemein (Wikipedia)

D

Data Transfer : wird im Java Kontext zusammen mit Cut&Paste und Drag and Drop verwendet

Demos : Demos-doku, github repo: SwingSet3-demos

dependences : projects in SwingSet3

DnD : steht für Drag and Drop

E

EDT : Event Dispatch Thread

F

G

GPX : GPS Exchange Format - ein XML-Datenformat mit Geo-Ortspunkten, -Routen und -Tracks

GUI : Graphical User Interface, Benutzeroberfläche, allgemein, siehe auch L&F (Look&Feel)

GVT : Batik Graphics Vector Tree (GVT) gehört zu Apache XML Graphics Project

H

I

J

JDNC : Java Desktop Network Component, s. BSAF

JPMS : Java Platform Module System, aka Modulsystem Jigsaw

JTextComponent, JTextField, JTextArea : siehe Prompt- und BuddySupport

K

Kenai : History of SwingLabs

L

L&F : als Look&Feel wird das Aussehen und Verhalten der Benutzeroberfäche bezeichnet.

LazyValue : TODO siehe MetalButtonPainterIssues

List, JList, JXList : Listen von Werten darstellen List, JList, JXList

M

maven central : Central OSSRH

N

Nimbus : Mit Java 1.6 wurde das cross-platform Look-and-Feel eingeführt. Es wird per properties konfiguriert, siehe Nimbus-UI-defaults

O

OSSRH : Open Source Software Repository Hosting, zentrales öffentliches Repository für Artefakte: Central-OSSRH

P

PLAF : steht für Pluggable Look And Feel

PromptSupport : erweitert Textkomponenten

public key server : siehe distributing-your-public-key

Q

R

Renderer : die Darstellung von mehr oder weniger komplexen Objekten auf der Benutzeroberfäche im gewählten Look&Feel

S

SAM : Single Abstract Method interface, Beispiel StringValue

SVG : Scalable Vector Graphics, XML-Beschreibung von Vektorgrafiken

SwingLabs : History of SwingLabs

SwingSet2 : github repo: SwingSet2-demos

SwingSet3 : github repo: SwingSet3, SwingSet3-demos

SwingX : package org.jdesktop.swingx SwingX

Synth : Seit Java 1.5 gibt es das Synth-Look-and-Feel, dessen Erscheinungsbild in einer XML-Datei beschrieben wird, s. Nimbus

T

Table : JXTable (de) erweitert javax.swing.JTable

Tests : Tests (de)

TextComponent : siehe Prompt- und BuddySupport

Tree : JXTree (de) erweitert javax.swing.JTree

TreeTable : JXTreeTable (de) ist ein Zwitter mit Eigenschaften von Tree und Table

Trident : Trident animation library (de)

U

UI : User Interface, Benutzerschnittstelle, allgemein, siehe auch GUI, L&F (Look&Feel)

V

W

X

Y

Z

Clone this wiki locally