禁用 JComboBox 时具有更好的可读性/对比度

发布于 2024-10-14 21:33:05 字数 315 浏览 4 评论 0 原文

我有一个 JComboBox,需要在某些时候禁用,但我觉得 disabled 状态使其很难阅读,因为它的对比度较低。

如果只有下拉箭头按钮显示为禁用,同时保持框渲染器处于启用状态,那就太好了。

实际:所需:

有没有一种简单的方法可以实现此目标或类似的目标?

谢谢!

I have a JComboBox that needs to be disabled at some point, but I am feeling that the disabled status makes it quite harder to read because the low contrast it has.

It would be nice if only the drop-down arrow button would be shown as disabled, while keeping the box renderer as if it were enabled.

Actual: actual combo Desired: desired result

Is there an easy way to achieve this or something similar?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

银河中√捞星星 2024-10-21 21:33:05

我最终查看了 BasicComboBoxUI,在那里我发现了这个:

        if ( comboBox.isEnabled() ) {
            c.setForeground(comboBox.getForeground());
            c.setBackground(comboBox.getBackground());
        }
        else {
            c.setForeground(DefaultLookup.getColor(
                     comboBox, this, "ComboBox.disabledForeground", null));
            c.setBackground(DefaultLookup.getColor(
                     comboBox, this, "ComboBox.disabledBackground", null));
        }

所以我使用 JLabel 作为渲染器组件,并重写了 setForeground 方法以不执行任何操作。因此,颜色永远不会改变并保持默认的黑色值。

问题是这个技巧是特定于实现的。给定的 Look&Feel 或 UI 管理器可能会执行其他操作,例如使用半透明层进行覆盖以显示禁用的项目,而不是更改组件的颜色:-(

如果安装的 L&F 或 UI 可能测试至少会发出警告Manager 不会调用 setForeground 方法。

I've ended up peeking the BasicComboBoxUI, where I've found this:

        if ( comboBox.isEnabled() ) {
            c.setForeground(comboBox.getForeground());
            c.setBackground(comboBox.getBackground());
        }
        else {
            c.setForeground(DefaultLookup.getColor(
                     comboBox, this, "ComboBox.disabledForeground", null));
            c.setBackground(DefaultLookup.getColor(
                     comboBox, this, "ComboBox.disabledBackground", null));
        }

So I've used as renderer component a JLabel with the setForeground method overriden to do nothing. Thus, the colour is never changed and keeps the default black value.

The problem is that this trick is implementation specific. A given Look&Feel or UI Manager might do other things like overpainting with a semi-transparent layer to display disabled items instead of changing the component's colours :-(

Maybe a test could at least give a warning if the installed L&F or UI Manager does not call the setForeground method.

木槿暧夏七纪年 2024-10-21 21:33:05

这是您的另一个选择:

    jComboBox1.setRenderer(new DefaultListCellRenderer() {
        @Override
        public void paint(Graphics g) {
            setForeground(Color.BLACK);
            super.paint(g);
        }
    });

您只需要在实例化后添加此代码。字母将始终保持黑色。如果禁用或启用,组合框框架将变成灰色或黑色。

它们看起来像这样:

在此处输入图像描述

Here is another option you have:

    jComboBox1.setRenderer(new DefaultListCellRenderer() {
        @Override
        public void paint(Graphics g) {
            setForeground(Color.BLACK);
            super.paint(g);
        }
    });

You will just need to add this code after the instantiation. The letters will always stay black. The combo box frame will turn to be either gray or black if you disable or enable.

They look like this:

enter image description here

怎会甘心 2024-10-21 21:33:05

这是另一个黑客,由于 Michael Grimes,它不应该受到特定外观和感觉的影响。诀窍是使组合框可编辑;当编辑器支持 setDisabledTextColor 方法时公开的 JTextField。由于您禁用了组合框,因此它的可编辑性并不重要!我用来执行此操作的代码(从 Scala 翻译)如下:

JComboBox cb = ...;
...
cb.setEditable(true);
ComboBoxEditor editor = cb.getEditor()
JTextField     etf    = (JTextField)etf.getEditorComponent()
etf.setDisabledTextColor(UIManager.getColor("ComboBox.foreground"));
etf.setBackground(UIManager.getColor("ComboBox.background"));
// editor.setItem(format(obj));
cb.setEnabled(false);

此处保证强制转换成功,因为我们使用 BasicComboBoxEditor,其文档说“编辑器是作为 JTextField 实现的”。出现注释掉的行是因为我正在使用自定义渲染器,该渲染器打印整数并在其周围添加额外的文本;调用 setItem 允许我指定类似的字符串,这是必要的,因为编辑器会忽略自定义渲染器。如果您使用默认渲染器,则无需担心该行;另一方面,如果您使用更复杂的渲染器,那么您可能需要完全执行其他操作。

尽管这是一个可怕的拼凑,但它有效,而且它似乎不依赖于任何实现定义的功能。我可以想象这种破坏的两个地方是(a),如果可编辑的组合框看起来与不可编辑的组合框非常不同(例如,我的第一次尝试没有改变文本字段的背景颜色,这使得它看起来错误) ,或 (b) 如果 BasicComboBoxEditor 停止返回 JTextField(这似乎不太可能)。但到目前为止,它符合我的目的。

Here's another hack, due to Michael Grimes, which shouldn't be affected by the particular look and feel. The trick is to make the combo box editable; the JTextField which is exposed as the editor supports the setDisabledTextColor method. And since you're disabling the combo box, it doesn't matter that it's editable! The code that I'm using to do this (translated from Scala) is the following:

JComboBox cb = ...;
...
cb.setEditable(true);
ComboBoxEditor editor = cb.getEditor()
JTextField     etf    = (JTextField)etf.getEditorComponent()
etf.setDisabledTextColor(UIManager.getColor("ComboBox.foreground"));
etf.setBackground(UIManager.getColor("ComboBox.background"));
// editor.setItem(format(obj));
cb.setEnabled(false);

The cast is guaranteed to succeed here because we're using a BasicComboBoxEditor, whose docs say "The editor is implemented as a JTextField." The commented-out line occurs because I'm using a custom renderer which prints integers with extra text surrounding them; calling setItem allows me to specify a similar string, and is necessary because the editor ignores the custom renderer. If you're using the default renderer, then you don't need to worry about that line; on the other hand, if you're using a more complicated renderer, then you might need to do something else entirely.

Despite the fact that this is a horrific kludge, it works, and it doesn't seem to rely on any implementation-defined features. The two places I could imagine this breaking are (a), if an editable combo box looks very different from an uneditable one (for instance, my first attempt didn't change the background color of the text field, which made it look wrong), or (b) if BasicComboBoxEditor stopped returning a JTextField (which seems less likely). But so far, it's serving my purposes.

反话 2024-10-21 21:33:05

试试这个
**

UIManager.put( "ComboBox.disabledBackground", new Color(212,212,210) );
UIManager.put( "ComboBox.disabledForeground", Color.BLACK );

**

Try this
**

UIManager.put( "ComboBox.disabledBackground", new Color(212,212,210) );
UIManager.put( "ComboBox.disabledForeground", Color.BLACK );

**

七色彩虹 2024-10-21 21:33:05

可以使用以下代码实现结果:

    Component editorComponent = comboBox.getEditor().getEditorComponent();
    if(editorComponent instanceof JTextComponent){
        ((JTextComponent)editorComponent).setDisabledTextColor(Color.black);
    }

我没有使用多个 L&F 对其进行测试,但它可能会产生影响,因为这会触发 PropertyChange 事件(“disabledTextColor”)。请参阅

The result can be achieved with the following code:

    Component editorComponent = comboBox.getEditor().getEditorComponent();
    if(editorComponent instanceof JTextComponent){
        ((JTextComponent)editorComponent).setDisabledTextColor(Color.black);
    }

I did not test it with several L&F, but it might make a difference, as this fires a PropertyChange event ("disabledTextColor"). Please see the docs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文