JavaSwingLookAndFeel: MenuItems


MenuItems

Claim: There is no need for JCheckBoxMenuItem nor JRadioButtonMenuItem nor separate UI delegate class IDs (and implementations) (nor even separate UIDefault keys in BasicLookAndFeel and descendants for most properties (except icons)). Things could have easily been done without.

JCheckBoxMenuItem is just a checkable ("selectable") menu items - whose ButtonModel is selectable (such a notion clearly belongs to ButtonModel)

JRadioButtonMenuItem is just a checkable menu item whose ButtonModel is in a ButtonGroup

Hints:

LAF code

BasicCheckBox/RadioButtonMenuItem do not have anything but dead code (processMouseEvent). (In fact they needn't as the ButtonModel/ButtonGroup alone will handle the selection).

Metal uses just the BasicXXXMenuItemUIs.

Motif adds subclasses to all three with almost exactly the same code (the plain MenuItemUI misses one isSelected() but it should never become selected anyway), and have the main work delegated to one method in MotifGraphicsUtils (which is not used otherwise)

Windows has unused classes for CheckBox/RadioButton, but changes the MenuItemUI, compare (#4685843)

(This can be seen by enabling mnemonic hiding and opening the menu: the mnemonics for JRadioButton/JCheckBoxMenuItems remain visible. Probably there are other differences in painting as well (or Windows wouldn't have rewritten the method completely). This looks like an oversight.

Synth has the MenuItemUIs copied from Basic (including the dead code)

Inspection of some custom LAFs show that they either miss installing their UI for RadioButton/CheckBoxMenuItems or reproduce essentially the same code in all three cases.

LAF properties

(The actual values are actually rather unimportant)

Basic

Metal

Motif

Windows

font

dialogPlain12

menuTextValue

dialogPlain12

MenuFont

acceleratorFont

only "MenuItem." used

dialogPlain12

subTextValue

dialogPlain12

MenuFont / missing / missing

background

"menu"

"menu"

MenuBackgroundColor

foreground

"menuText"

"menuText"

MenuTextColor

selectionBackground

"textHighlightText"

menuSelectedBackground

menuItemPressedBackground

SelectionBackgroundColor

selectionForeground

"textHighlight"

menuSelectedForeground

menuItemPressedForeground

SelectionTextColor

disabledForeground

only MenuItem. used

null

menuDisabledForeground

InactiveTextColor / missing? / InactiveTextColor

acceleratorForeground

"menuText"

acceleratorForeground

MenuTextColor

acceleratorSelectionForeground

"textHighlightText"

acceleratorSelectedForeground

SelectionTextColor

acceleratorDelimiter

only "MenuItem." used

menuItemAcceleratorDelimiter

menuItemAcceleratorDelimiter / missing / missing

border

marginBorder

menuItemBorder

menuMarginBorder

marginBorder / missing/ missing

borderPainted

false

true

(updated by ChangeListener)

margin

(2,2,2,2)

checkIcon

menuItemCheckIcon / radioButtonMenuItemIcon / checkBoxMenuItemIcon

getMenuItemCheckIcon=null / CheckBoxMenuItemIcon / RadioButtonMenuIcon

menuItemCheckIcon / checkBoxIcon / radioButtonIcon

menuItemCheckIcon / missing? / missing?

arrowIcon

menuItemArrowIcon

getMenuItemArrowIcon

menuItemArrowIcon

menuItemArrowIcon / missing? / missing?

commandSound

null

MenuItemCommand

win.sound.menuCommand

"missing?" does not mean that it is not known, but that is highly questionable that this is intended.

Observations: Except for the checkIcon, none of the properties are set to any different value.

Even if some properties are only used in the "MenuItem." version, sometimes all three keys are set.

The purpose of checkIcon (menuItem) and arrowIcon (all) seems to be to fill space to align items better (This already fails in BasicLookAndFeel where the radioButton icon is smaller and is unused in Metal).

(Somewhen, the layout was extended to align separately on text and accelerator (#4113639), probably this should have been cleared up then).

The layout places the checkIcon first, then icon/text; arrowIcon on the right (trailing) side (#4199382).

Icon

Which Icon will be chosen when (Implementation details)?

Basic/Metal

Motif

getPreferredSize

icon

not overridden

layout for painting

icon

same strategy

painting

icon != null:

!enabled => disabledIcon (note: possibly auto-created by AbstractButton)

pressed && armed =>pressedIcon (or icon)

else icon

same strategy

At least I would expect that selected => selectedIcon (or icon), disabled && selected => selectedDisabledIcon (or disabledIcon), and possibly use rollover(Selected)Icon instead of pressedIcon.

See (#4776403), (#4419531)

Historical differences (minimal)

BasicCheckBoxMenuItemUI/BasicRadioButtonMenuItemUI did set the "checkIcon" as the menu item's selected icon (uselessly, the selected icon was unused by the painting code). This code has been removed with JDK1.4.0beta2.

Windows did not have a MenuItemUI (It was introduced in JDK1.4.0beta1 (or somewhen in 1.3.1?))

Suggestions

Do not use different UI for the three types of MenuItems. It only complicates everything. As it is the button model that handles the selection anyway, there is no need for explicit LAF code.


(C) 2001-2009 Christian Kaufhold (swing@chka.de)