【问题标题】:Customizing JComboBox with nimbus使用 nimbus 自定义 JComboBox
【发布时间】:2013-06-21 10:13:54
【问题描述】:

我正在尝试使用 nimbus L&F 自定义 JComboBox 的外观。

这是一些代码:

NamedPainter.java

package gui.combo;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;

import javax.swing.JComponent;
import javax.swing.Painter;

public class NamedPainter implements Painter<JComponent>
{
    String name;

    public NamedPainter(String name)
    {
        this.name = name;
    }

    @Override
    public void paint(Graphics2D g, JComponent object, int width, int height)
    {
        g.setColor(Color.LIGHT_GRAY);
        g.fillRect(0, 0, width, height);
        g.setFont(new Font("Arial", Font.PLAIN, 12));
        g.setColor(Color.YELLOW);
        g.drawString(name, 0, 10);
    }
}

ColorRectanglePainter.java

package gui.combo;

import java.awt.Color;
import java.awt.Graphics2D;

import javax.swing.JComponent;
import javax.swing.Painter;

public class ColorRectanglePainter implements Painter<JComponent>
{

    private final Color color;

    public ColorRectanglePainter(final Color color)
    {
        this.color = color;
    }

    @Override
    public void paint(Graphics2D g, JComponent object, int width, int height)
    {
        g.setColor(color);
        g.fillRect(0, 0, width, height);
    }

}

CustomizeComboNimbus.java

package gui.combo;

import java.awt.Color;
import java.awt.Container;
import java.awt.GridLayout;
import java.util.Map.Entry;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

public class CustomizeComboNimbus
{

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        // Set nimbus L&F
        try
        {
            for(LookAndFeelInfo info : UIManager.getInstalledLookAndFeels())
            {
                if("Nimbus".equals(info.getName()))
                {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        }

        catch(Exception e)
        {
            // No nimbus...
            e.printStackTrace();
            return;
        }

        ColorRectanglePainter redPainter = new ColorRectanglePainter(Color.RED);

        // Get default UI and modify it 
        final UIDefaults boxDefaults = new UIDefaults();
        for(Entry<Object, Object> entry : UIManager.getLookAndFeelDefaults().entrySet())
        {
            try
            {
                String key = (String)entry.getKey();
                if(key.startsWith("ComboBox"))
                {
                    if(key.contains("Painter"))
                    {
                        if(key.contains("arrowButton"))
                        {
                            // Set a painter which paint a red rectangle for arrowButton
                            boxDefaults.put(key, redPainter);
                            System.err.println("Replacing the painter for " + key + " with redPainter");
                        }
                        else
                        {
                            // Set a painter that display the name of the nimbusKey when it is triggered
                            NamedPainter painter = new NamedPainter(key);
                            boxDefaults.put(key, painter);
                            System.err.println("Replacing the painter for " + key + " with NamedPainter");
                        }
                    }
                }
            }
            catch(Exception e)
            {
            }
        }

        final String[] toDisplay = { "Hello", "World", "Pimp", "My", "Combo" };

        SwingUtilities.invokeLater(new Runnable()
        {

            @Override
            public void run()
            {
                JFrame frame = new JFrame("Pimp my combo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                JComboBox<String> classicCombo = new JComboBox<>(toDisplay);
                JComboBox<String> pimpedCombo = new JComboBox<>(toDisplay);
                // set the modif to pimpedCombo
                pimpedCombo.putClientProperty("Nimbus.Overrides", boxDefaults);
                pimpedCombo.putClientProperty("Nimbus.Overrides.InheritDefaults", false);

                Container pane = frame.getContentPane();
                pane.setLayout(new GridLayout(2, 1));
                pane.add(classicCombo);
                pane.add(pimpedCombo);
                frame.pack();
                frame.setVisible(true);
            }
        });

    }
}

这是控制台输出:

Replacing the painter for ComboBox:"ComboBox.arrowButton" Editable+Selected].backgroundPainter with redPainter
Replacing the painter for ComboBox:"ComboBox.textField"[Enabled].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Pressed].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Editable+Focused].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Disabled].foregroundPainter with redPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Editable+MouseOver].backgroundPainter with redPainter
Replacing the painter for ComboBox[Enabled+Selected].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[MouseOver].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Selected].foregroundPainter with redPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Disabled+Editable].backgroundPainter with redPainter
Replacing the painter for ComboBox[Editable+Pressed].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Focused+Pressed].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Disabled+Pressed].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Editable+Enabled].backgroundPainter with redPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Enabled].foregroundPainter with redPainter
Replacing the painter for ComboBox[Disabled+Editable].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[MouseOver].foregroundPainter with redPainter
Replacing the painter for ComboBox[Disabled].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.textField"[Disabled].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Enabled].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Editable+MouseOver].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.textField"[Selected].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Focused].backgroundPainter with NamedPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Editable+Pressed].backgroundPainter with redPainter
Replacing the painter for ComboBox:"ComboBox.arrowButton"[Pressed].foregroundPainter with redPainter
Replacing the painter for ComboBox[Editable+Enabled].backgroundPainter with NamedPainter
Replacing the painter for ComboBox[Focused+MouseOver].backgroundPainter with NamedPainter

当然还有它的样子:

然而,这并不是我所期望的!我认为用自定义 redPainter 替换了所有 ComboBox:arrowButtonPainter,我不会看到黑色(或白色)小三角形箭头,而只会看到一个红色矩形。 另外,我没有经理来更改前景文本的颜色。如何在组合和选择弹出菜单中做到这一点?

[编辑]

进一步调查:我尝试使用 UIManager.getLookAndFeelDefaults().put 而不是 boxDefaults.put 放置属性,并且我得到了箭头按钮的预期结果,它显示为红色方块(显然对于经典组合和拉皮条组合)。所以,我想我做错了什么是覆盖了拉皮条组合的属性,即我从Jasper Pott's blog得到的两行代码

pimpedCombo.putClientProperty("Nimbus.Overrides", boxDefaults);
pimpedCombo.putClientProperty("Nimbus.Overrides.InheritDefaults", false);

有人可以帮忙吗?

[编辑 2]

如果我使用 UIManager.put 而不是 UIManager.getLookAndFeelDefaults().put,我还注意到不一致的行为,其中箭头按钮将显示为红色,例如仅在 mouseOver 或单击等时。Javadoc 说 UIManger.put 仅影响“开发人员默认值”,不是 L&F 的默认值。有什么不同?任何帮助,链接到关于一切如何工作的优秀文档都会有所帮助。

【问题讨论】:

  • 你可以试试here显示的方法。
  • 试过但没有用。不幸的是,对于 Basic 和 Nimbus L&F...

标签: java swing jcombobox nimbus


【解决方案1】:

Nimbus.Overrides 例如内部组件(例如 JComboBox 内部的 JTextField)不起作用。我在 UIManager.getLookAndFeelDefaults() 中添加了必要的绘制器,并实现了自定义逻辑,用于按实例分离父控件。

【讨论】:

    猜你喜欢
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-21
    相关资源
    最近更新 更多