如何自定义JComboBox的外观?

3
我想制作一个下拉列表,长这样:

alt text

JComboBox提供了我所需的功能,因此我不需要编写自定义组件。但我找不到一种方法来定制整个JComboBox的外观以实现这一点。有什么建议吗?
更新:我不希望所有的JComboBox都看起来像这样。我只想创建一个具有这种自定义外观的JComboBox。因此,据我所知,创建自定义L&F不是解决方案。

请查看Sun关于LnFs的教程,了解有关Synth的更多详细信息。同时,也可以参考编写自定义Swing组件的方法 - willcodejavaforfood
@Stephane,最终我创建了一个自定义组件。 - Steve McLeod
我遇到了同样的问题...你能分享一下你的自定义组件吗? - sirbris
2个回答

9

JComboBox UI 由文本框、列表和箭头组成。要自定义它们,您可以使用一些现成的 L&F 或者使用 Synth L&F 实现最容易。

初始化 L&F:

SynthLookAndFeel lookAndFeel = new SynthLookAndFeel();

try {
    lookAndFeel.load(YourClassAlongWithSynthXml.class.getResourceAsStream("synth.xml"), YourClassAlongWithSynthXml.class);
} catch (ParseException e) {
    e.printStackTrace();
}

UIManager.setLookAndFeel(lookAndFeel);

当synth.xml文件包含以下内容时:

<style id="textfield">
    <insets top="4" left="6" bottom="4" right="6" />

    <state>
        <font name="Verdana" size="12" />

        <!--
        <color type="BACKGROUND" value="#D2DFF2" />
        -->
        <color type="TEXT_FOREGROUND" value="#003c2d" />
    </state>

    <imagePainter method="textFieldBorder" path="images/textfield.png" sourceInsets="4 6 4 6" paintCenter="false" />
</style>

<bind style="textfield" type="region" key="TextField" />

<style id="arrowStyle">
    <imagePainter method="arrowButtonForeground" path="images/arrow-up.png" sourceInsets="0 0 0 0" stretch="false" direction="north" />
    <imagePainter method="arrowButtonForeground" path="images/arrow-down.png" sourceInsets="0 0 0 0" stretch="false" direction="south" />
    <imagePainter method="arrowButtonForeground" path="images/arrow-left.png" sourceInsets="0 0 0 0" stretch="false" direction="west" />
    <imagePainter method="arrowButtonForeground" path="images/arrow-right.png" sourceInsets="0 0 0 0" stretch="false" direction="east" />
</style>

<bind key="ArrowButton" type="region" style="arrowStyle" />

<style id="comboArrowStyle">
    <imagePainter method="arrowButtonForeground" path="images/combobox-arrow.png" sourceInsets="0 0 0 0" stretch="false" direction="south" />
</style>

使用Synth L&F,您需要完全定义UI组件的外观,而不能仅仅使用默认设置。

但是如果您只需要简单地修改颜色并重用默认L&F,则可以使用以下代码片段来初始化组合框的UI:

final Color COLOR_BUTTON_BACKGROUND = Color.decode("#d3dedb");

UIManager.put("ComboBox.buttonBackground", COLOR_BUTTON_BACKGROUND);
UIManager.put("ComboBox.buttonShadow", COLOR_BUTTON_BACKGROUND);
UIManager.put("ComboBox.buttonDarkShadow", COLOR_BUTTON_BACKGROUND);
UIManager.put("ComboBox.buttonHighlight", COLOR_BUTTON_BACKGROUND);

如果我想改变所有组合框的外观,那么这很好。但是我只想创建一个具有此自定义外观的组合框。 - Steve McLeod
如何通过UIManager更改arrowStyle? - Stephane Grenier

2

如果您不想创建整个外观,最简单的方法是子类化jcombobox并覆盖paintComponent方法,并绘制您想要的任何内容。

用您的灰色填充背景,然后用较浅的颜色绘制您的文本和箭头。

如果您选择这种方法,您可能还需要覆盖updateUI方法,以便如果VM尝试更新您的外观,您的组合框不会回到错误的颜色。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接