jcombobox弹出菜单

问题描述:

我希望的是,当键入可编辑的 JCombobox JCombobox Popup菜单时,看起来像是自动的,我做到了,有效 .但是,当我在JCombobox中更改了箭头按钮 Icon 时,它不再起作用,如图所示

What I am hoping is, when typing in editable JCombobox , the Popup Menu of the JCombobox to appear autumaticaly , i did this and it worked . But, when i changed the Icon of the Arrow Button in the JCombobox it didnt worked any more as shown in the picture

在更改箭头按钮图标

更改箭头按钮图标后(当人们在JCombobox中写入内容时,弹出窗口永不出现)

After changing Arrow Button Icon (the Popup never appears, when one writes in the JCombobox)

这就是我所做的:

JTextComponent editor;
/** Creates new form combo */
public combo() {
    initComponents();

    editor = (JTextComponent) jComboBox1.getEditor().getEditorComponent();
    jComboBox1.setEditable(true);

    editor.addKeyListener(new KeyAdapter() {
        @Override
        public void keyReleased(KeyEvent e) {

            char keyChar = e.getKeyChar();
            if (jComboBox1.isDisplayable()) 
            { 
                jComboBox1.setPopupVisible(true);    
            }
            editor.setCaretPosition(editor.getText().length());

            //  System.out.println("wwwweeeee"+keyChar);
        }
    });    

    jComboBox1.setUI(new SynthComboBoxUI() {
        protected JButton createArrowButton() {

            JButton btn = new JButton();
            btn.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Image/error3.png")));            
            return btn;
        }
    });
}    

Pleeeese的帮助,因为我真的很难找到解决方案

Pleeeese help because i'm really tired from searching for a solution

此处的技术问题是,编辑器是由ui创建/维护的.设置自定义ui时,它会被新的编辑器替换,因此您正在侦听的组件已不再是容器层次结构的一部分.

The technical problem here is that the editor is created/maintained by the ui. When setting a custom ui it is replaced by a new editor, so you are listening to a component that is no longer part of the container hierarchy.

进行一些挖掘之后...我仍然没有解决方案:-(从表面上看,您可以在编辑器上安装侦听器之前调用setUI -但是调用setUI总是 错误...所以就不要这么做.

After digging a bit ... I still don't have a solution :-( On face value, you'd call setUI before installing the listener on the editor - BUT calling setUI is always wrong ... so simply don't.

看到ui是基于合成器的,更新其视觉前端/背景属性的正确方法是为每个应用程序或每个实例提供自定义的绘画工具. Nimbus专门允许通过"Nimbus.Overrides"客户端属性安装每个实例的自定义UIDefaults.要更改箭头按钮上的图标,适当的替代值应为

Seeing that the ui is synth-based, the correct way to update its visual fore/background properties is to supply custom painters, per-application or per-instance. Nimbus specifically allows to install per-instance custom UIDefaults via the "Nimbus.Overrides" client property. For changing the icon on the arrow button, the appropriate override would be

Painter core = // a custom painter which paints the icon 
comboDefaults.put("ComboBox:\"ComboBox.arrowButton\"[Enabled].foregroundPainter", core);
combo.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
combo.putClientProperty("Nimbus.Overrides", comboDefaults);

一切正常,除了不能正常工作-看起来覆盖未正确安装在子代上.

All fine, except not working - looks like the overrides are not properly installed on the children.

编辑2

...几小时后...

... hours later ...

从所有可用资源中,上述方法应该可以正常工作,请参阅f.i. Jasper关于如何定义自定义属性的初步解释:

from all available resources, the above should work, see f.i. Jasper's initial explanation of how-to define custom properties:

ComponentA:ChildComponentB.foreground,通过它可以指定ComponentA中包含的ChildComponentB.

ComponentA:ChildComponentB.foreground which lets you specify a ChildComponentB contained within ComponentA.

因此,我怀疑这确实是一个错误.一个不太令人满意的破解方法是在按钮本身上安装替代:

So I suspect it's really a bug. A not really satisfying hack-around is to install the override on the button itself:

JButton org = null;
for (int i = 0; i < combo.getComponentCount(); i++) {
    if (combo.getComponent(i) instanceof JButton) {
        org = (JButton) combo.getComponent(i);
        UIDefaults buttonDefaults = new UIDefaults();
        buttonDefaults.put("ComboBox:\"ComboBox.arrowButton\"[Enabled].foregroundPainter", painter);
        org.putClientProperty("Nimbus.Overrides.InheritDefaults", false);
        org.putClientProperty("Nimbus.Overrides", buttonDefaults);
        break;
    }
}

这根本不能令人满意,因为按钮的创建是由ui委托控制的,因此此配置将无法在LAF切换后幸存下来.或相反:您将需要使用UIManager安装PropertyChangeListener,并在检测到对Nimbus的切换时,手动将替代项从组合复制到其子项.

That's not satisfying at all, as the button creation is controlled by the ui delegate, so this config will not survive a switch of LAF. Or the other way round: you'll need a install a PropertyChangeListener with the UIManager and on detecting a switch to Nimbus, manually copy the overrides from the combo to its children.