Reputation: 181
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
After changing Arrow Button Icon (the Popup never appears, when one writes in the JCombobox
)
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
Upvotes: 2
Views: 1023
Reputation: 51525
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.
Upvotes: 5