java - Strange tab-order with editable JComboBoxes -
i've got jframe
looks this:
it's got 2 jtextfield
s on it, 1 jcombobox
between them , jpanel
@ bottom (that can't see).
one of features of jcombobox
can given custom editor. these implement comboboxeditor
interface. in each of following 3 cases, gui looks same, , have expected them behave same:
- i not specify custom editor, , use default one.
- i create custom editor editor component
jtextfield
. - i create custom editor editor component
jpanel
jtextfield
on (usingborderlayout
).
when editor editable combo box set default, pressing tab moves focus top jtextfield
editing area on jcombobox
, other jtextfield
. if create custom editor editor component jtextfield
, otherwise expect, same thing happens.
but, if instead create custom editor editor component jpanel
jtextfield
add
ed it, focus makes 1 additional stop. if focus on top jtextfield
, pressing tab moves focus little arrow @ right of editable combo box before moving text area.
why happening? focus never moves on jpanel
@ bottom of frame, why presence of jpanel
holding jtextfield
affect tab order on combo box?
the following s(-ish)scce, has 1 text field , 3 types of combo box on it:
import javax.swing.*; import java.awt.event.*; import java.awt.borderlayout; import java.awt.component; import java.awt.container; import java.awt.dimension; public class comboboxtest extends jframe { private jpanel layoutpanel; private jtextfield meaninglesstextfield; private jcombobox defaulteditorcombobox; private jcombobox textfieldeditorcombobox; private jcombobox paneleditorcombobox; public comboboxtest() { setdefaultcloseoperation(windowconstants.exit_on_close); layoutpanel = new jpanel(); layoutpanel.setlayout(new boxlayout(layoutpanel, boxlayout.y_axis)); meaninglesstextfield = new jtextfield(); defaulteditorcombobox = new jcombobox(); // default jcombobox. defaulteditorcombobox.seteditable(true); textfieldeditorcombobox = new jcombobox(); textfieldeditorcombobox.seteditable(true); textfieldeditorcombobox.seteditor(new textfieldeditor()); paneleditorcombobox = new jcombobox(); paneleditorcombobox.seteditable(true); paneleditorcombobox.seteditor(new paneleditor()); layoutpanel.add(box.createrigidarea(new dimension(500,0))); layoutpanel.add(meaninglesstextfield); layoutpanel.add(defaulteditorcombobox); layoutpanel.add(textfieldeditorcombobox); layoutpanel.add(paneleditorcombobox); container contentpane = getcontentpane(); contentpane.add(layoutpanel, borderlayout.center); pack(); } public static void main(string[] args) { java.awt.eventqueue.invokelater(new runnable() { @override public void run() { new comboboxtest().setvisible(true); } }); } private class paneleditor extends jpanel implements comboboxeditor { public jtextfield inputtextfield = new jtextfield(); public paneleditor() { setlayout(new borderlayout()); add(inputtextfield, borderlayout.center); } @override public string getitem() { return inputtextfield.gettext(); } @override public void setitem(object newtext) { if (newtext != null) { inputtextfield.settext(newtext.tostring()); } else { inputtextfield.settext(""); } } @override public component geteditorcomponent() { return this; } @override public void removeactionlistener(actionlistener listener) { inputtextfield.removeactionlistener(listener); } @override public void addactionlistener(actionlistener listener) { inputtextfield.addactionlistener(listener); } @override public void selectall() { inputtextfield.selectall(); } } private class textfieldeditor extends paneleditor implements comboboxeditor { // same, except editor component jtextfield // rather whole panel. public textfieldeditor() { } @override public jtextfield geteditorcomponent() { return inputtextfield; } } }
note: behaviour becomes problem if want add jlabel
editor. have put jpanel
there hold both label , text field.
the basic problem combo's ui delegate can't handle compound editor components. there several places assumes editor component target of whatever configuration needs do. concrete mis-behaviour here explicitly sets editor's focusability of combo itself
// in basiccomboboxui protected void configureeditor() { .... editor.setfocusable(combobox.isfocusable()); .... ]
the implications
- by default, panel's focusable true because combo's true
- forcing panel's focusable false in constructor has no effect (the ui resets later on , whenever laf switched)
- disabling combo's focusable disables panel's well
to fix on level of editor, can implement isfocusable return false unconditionally:
private class paneleditor extends jpanel implements comboboxeditor public boolean isfocusable() { return false; } ... }
an aside: code hygiene, better not extend view implement role comboboxeditor (even though here need subclassed jpanel avoid problem, it's arguably borderline :-) - instead implement editor , let use tweaked panel.
also beware might stumble more problems compound editor (check code of basiccomboui more places assumes plain childless component), might consider not doing @ think of different way achieve requirement.
Comments
Post a Comment