使用Synth将自定义渲染器绑定到ComboBox

时间:2018-02-06 03:17:29

标签: java swing combobox synth

我使用Synth定制我的LAF,现在我正在使用ComboBox,这让我很困惑。我查看了ComponentProperties Table并找到了ComboBox.listRenderer属性,该属性指定了JComboBox列表的渲染器。问题是我不知道如何将自己的渲染器绑定到它。我之前找到了一些答案:

<style id="ComboBoxListRenderer">
     <opaque value="true"/>
     <state>
          <color type="TEXT_FOREGROUND" value="BLACK" />
     </state>
</style>
<bind style="ComboBoxListRenderer" type="name" key="ComboBox.listRenderer"/>

这确实有效,但它只会更改默认的SynthComboBoxRenderer行为,而我无法将自己的渲染器类ui.MyComboBoxRenderer绑定到它。我也试过了

   <style id="comboBox">
        ...
        <object id="ComboBoxListRenderer" class="ui.MyComboBoxListRenderer"/>
        <property key="ComboBox.listRenderer" type="idref" value="ComboBoxListRenderer"/>
        ...
    </style>
    <bind style="comboBox" type="region" key="ComboBox"/>
可悲的是,这次没有任何事情发生。知道如何将自定义渲染器应用于所有ComboBox?感谢。

1 个答案:

答案 0 :(得分:0)

我设法弄明白了。对于寻求解决方案的任何人,您需要使用自己的SynthComboBoxUI覆盖MyComboBoxUI,并在您的用户界面中提供自定义渲染器。例如:

public class MyComboBoxUI extends SynthComboBoxUI {
    //Important! You must define this method and return your own UI class,
    //otherwise Synth will invoke its own *createUI* method and return
    //SynthComboBoxUI instead, which means all your efforts below will be in vain.
    public static ComponentUI createUI(JComponent c) {
        return new MyComboBoxUI();
    }

    //override this method to provide your own list renderer
    @Override
    protected ListCellRenderer<Object> createRenderer() {
        return new MyComboBoxRenderer();
    }

    //custom ListRenderer class
    @SuppressWarnings("serial")
    private class MyComboBoxRenderer extends JLabel implements ListCellRenderer<Object>, UIResource {
        public MyComboBoxRenderer() {
            super();
            setText(" ");
        }

        @Override
        public String getName() {
            // SynthComboBoxRenderer should have installed Name while constructor is working.
            // The setName invocation in the SynthComboBoxRenderer() constructor doesn't work
            // because of the opaque property is installed in the constructor based on the
            // component name (see GTKStyle.isOpaque())
            String name = super.getName();

            return name == null ? "ComboBox.renderer" : name;
        }

        @Override
        public Component getListCellRendererComponent(JList<?> list, Object value,
                         int index, boolean isSelected, boolean cellHasFocus) {
            //implementations
            ...

            // The renderer component should inherit the enabled and
            // orientation state of its parent combobox.  This is
            // especially needed for GTK comboboxes, where the
            // ListCellRenderer's state determines the visual state
            // of the combobox.
            if (comboBox != null){
                setEnabled(comboBox.isEnabled());
                setComponentOrientation(comboBox.getComponentOrientation());
            }

            return this;
        }
    }
}

XML文件:

<style id="comboBox">
    <insets top="3" left="6" bottom="3" right="6"/>
    <!--fill the full class name in the *value* attribute and synth will do the magic-->
    <defaultsProperty key="ComboBoxUI" type="String" value="ui.MyComboBoxUI"/>
    <state>
        <imagePainter method="comboBoxBackground" path="combobox_normal.png"
            sourceInsets="2 2 2 2"/>
    </state>
</style>
<bind style="comboBox" type="region" key="ComboBox"/>