如何自定义JComboBox的外观?

时间:2023-01-29 13:14:32

I'd like to make a drop-down list that looks like this:

我想制作一个如下所示的下拉列表:

alt text http://i44.tinypic.com/v80z81.png

替代文字http://i44.tinypic.com/v80z81.png

JComboBox provides the functionality I need, so I shouldn't need to write a custom component. But I can't find a way to customise the entire appearance of a JComboBox to achieve this. Any suggestions?

JComboBox提供了我需要的功能,因此我不需要编写自定义组件。但我无法找到一种方法来自定义JComboBox的整个外观来实现这一目标。有什么建议?

Update: I don't want all JComboBoxes to look like this. I only want to create one with this custom appearance. So as far as I can tell, creating a custom L&F is not the solution.

更新:我不希望所有JComboBox都像这样。我只想用这个自定义外观创建一个。据我所知,创建自定义L&F不是解决方案。

2 个解决方案

#1


JComboBox UI is composed from textfield, list and arrows. To customize them you can use some ready L&F or implement your most easily with Synth L&F.

JComboBox UI由文本字段,列表和箭头组成。要定制它们,您可以使用一些现成的L&F或使用Synth L&F轻松实现。

Initialize L&F:

SynthLookAndFeel lookAndFeel = new SynthLookAndFeel();

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

UIManager.setLookAndFeel(lookAndFeel);

Where synth.xml contains something like this:

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>

With Synth L&F you will need to fully define how your UI components look like you can't just.

使用Synth L&F,您需要完全定义UI组件的外观,而不仅仅是这样。

But if you just need to simply modify colors reusing your default L&F, you can use the following snippets to initialize UI of combo box:

但是,如果您只需要重新使用默认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);

#2


If you don't want to create an entire look and feel, the simplest answer is to subclass jcombobox and override the paintComponent method and draw whatever you want.

如果你不想创建一个完整的外观,最简单的答案是子类jcombobox并覆盖paintComponent方法并绘制你想要的任何东西。

fill the background with your gray color, then draw your text and arrow in your lighter color.

用你的灰色填充背景,然后用浅色绘制你的文字和箭头。

if you go this route, you may also need to override the updateUI method so that if the VM tries to update your look and feel your combo box doesn't go back to the wrong colors.

如果你走这条路线,你可能还需要覆盖updateUI方法,这样如果VM试图更新你的外观并感觉你的组合框没有回到错误的颜色。

#1


JComboBox UI is composed from textfield, list and arrows. To customize them you can use some ready L&F or implement your most easily with Synth L&F.

JComboBox UI由文本字段,列表和箭头组成。要定制它们,您可以使用一些现成的L&F或使用Synth L&F轻松实现。

Initialize L&F:

SynthLookAndFeel lookAndFeel = new SynthLookAndFeel();

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

UIManager.setLookAndFeel(lookAndFeel);

Where synth.xml contains something like this:

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>

With Synth L&F you will need to fully define how your UI components look like you can't just.

使用Synth L&F,您需要完全定义UI组件的外观,而不仅仅是这样。

But if you just need to simply modify colors reusing your default L&F, you can use the following snippets to initialize UI of combo box:

但是,如果您只需要重新使用默认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);

#2


If you don't want to create an entire look and feel, the simplest answer is to subclass jcombobox and override the paintComponent method and draw whatever you want.

如果你不想创建一个完整的外观,最简单的答案是子类jcombobox并覆盖paintComponent方法并绘制你想要的任何东西。

fill the background with your gray color, then draw your text and arrow in your lighter color.

用你的灰色填充背景,然后用浅色绘制你的文字和箭头。

if you go this route, you may also need to override the updateUI method so that if the VM tries to update your look and feel your combo box doesn't go back to the wrong colors.

如果你走这条路线,你可能还需要覆盖updateUI方法,这样如果VM试图更新你的外观并感觉你的组合框没有回到错误的颜色。