2

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

before changing Arrow Button Icon

enter image description here

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

enter image description here

this is what i did :

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 help because i'm really tired from searching for a solution

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Calm Sea
  • 181
  • 2
  • 4
  • 15
  • 1
    +1 to increase your Reputation :-) – nIcE cOw Aug 20 '12 at 15:18
  • @Calm Sea, "*But, when i changed the Icon of the Arrow Button in the JCombobox it didnt worked any more as shown in the picture*". What picture? Upload the image to [imgur](http://imgur.com/) and post the link. – user1329572 Aug 20 '12 at 15:34
  • @user1329572 : The OP's Reputation is not enough to post pictures along with the question. One needs to have more than 10 Reputation Points to post one, that's why that image is missing :-) – nIcE cOw Aug 20 '12 at 15:36
  • See also [*How can I change the arrow style in a JComboBox*](http://stackoverflow.com/q/3008447/230513). – trashgod Aug 20 '12 at 18:15
  • ok thanks user1329572 here is the link of the first image and this for the second http://imgur.com/UkSfg – Calm Sea Aug 20 '12 at 22:24
  • and this is for the second http://imgur.com/CanWe – Calm Sea Aug 20 '12 at 22:31
  • @trashgod i want to change the icon with my own one not the color of it – Calm Sea Aug 20 '12 at 22:42
  • @CalmSea: Try `setIcon()` & `setSelectedIcon()` on a `BasicArrowButton`, as mKorbel suggests. – trashgod Aug 20 '12 at 23:49
  • replacing the icon and the button yourself; probably means that the actionlisteners on the button that does the "popping up" are not there. therefore, go the stylistic route. – Jill Aug 20 '12 at 23:56
  • 1
    @trashgod setting the icons has ... zero effect, even if it where a BasicArrowButton: the shape is drawn directly, no icon used :-) – kleopatra Aug 21 '12 at 08:05
  • @trashgod thank , but setIcon() & setSelectedIcon() on a BasicArrowButton didnt work either – Calm Sea Aug 25 '12 at 20:55
  • @Jill Renee can explain more please , what do you mean by stylistic route? – Calm Sea Aug 25 '12 at 21:11

1 Answers1

5

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.

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.

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.

Edit 2

... hours later ...

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

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;
    }
}

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.

kleopatra
  • 51,061
  • 28
  • 99
  • 211
  • @kleopatra thanks alot for clarifying what problem was. but could please give me an example of how to use PropertyChangeListener with the UIManager ? – Calm Sea Aug 22 '12 at 11:24
  • +1 i tried the following , but nothing changed : UIDefaults comboDefaults = new UIDefaults(); comboDefaults.put("ComboBox:\"ComboBox.arrowButton\"[Enabled].foregroundPainter", new Painter() { @Override public void paint(Graphics2D g, JComponent c, int w, int h) { g.setColor(Color.WHITE); } }); jComboBox1.putClientProperty("Nimbus.Overrides.InheritDefaults", false); jComboBox1.putClientProperty("Nimbus.Overrides", comboDefaults); – Calm Sea Aug 24 '12 at 17:54