48 |
import java.awt.Rectangle; |
import java.awt.Rectangle; |
49 |
import java.awt.event.KeyEvent; |
import java.awt.event.KeyEvent; |
50 |
import java.awt.event.MouseEvent; |
import java.awt.event.MouseEvent; |
51 |
import java.beans.PropertyChangeEvent; |
import java.awt.event.ItemEvent; |
52 |
import java.beans.PropertyChangeListener; |
import java.awt.event.ItemListener; |
53 |
import java.util.ArrayList; |
import java.util.ArrayList; |
54 |
|
|
55 |
|
import javax.swing.ButtonModel; |
56 |
import javax.swing.Icon; |
import javax.swing.Icon; |
57 |
|
import javax.swing.JCheckBoxMenuItem; |
58 |
import javax.swing.JComponent; |
import javax.swing.JComponent; |
59 |
import javax.swing.JMenu; |
import javax.swing.JMenu; |
60 |
import javax.swing.JMenuItem; |
import javax.swing.JMenuItem; |
61 |
import javax.swing.JPopupMenu; |
import javax.swing.JPopupMenu; |
62 |
import javax.swing.KeyStroke; |
import javax.swing.KeyStroke; |
63 |
|
import javax.swing.LookAndFeel; |
64 |
import javax.swing.MenuElement; |
import javax.swing.MenuElement; |
65 |
import javax.swing.MenuSelectionManager; |
import javax.swing.MenuSelectionManager; |
66 |
import javax.swing.SwingConstants; |
import javax.swing.SwingConstants; |
112 |
* Number of spaces between icon and text. |
* Number of spaces between icon and text. |
113 |
*/ |
*/ |
114 |
protected int defaultTextIconGap = 4; |
protected int defaultTextIconGap = 4; |
115 |
|
|
116 |
/** |
/** |
117 |
* Color of the text when menu item is disabled |
* Color of the text when menu item is disabled |
118 |
*/ |
*/ |
159 |
private String acceleratorDelimiter; |
private String acceleratorDelimiter; |
160 |
|
|
161 |
/** |
/** |
162 |
* PropertyChangeListener to listen for property changes in the menu item |
* ItemListener to listen for item changes in the menu item |
163 |
*/ |
*/ |
164 |
private PropertyChangeListener propertyChangeListener; |
private ItemListener itemListener; |
165 |
|
|
166 |
/** |
/** |
167 |
* Number of spaces between accelerator and menu item's label. |
* Number of spaces between accelerator and menu item's label. |
168 |
*/ |
*/ |
169 |
private int defaultAcceleratorLabelGap = 4; |
private int defaultAcceleratorLabelGap = 10; |
170 |
|
|
171 |
/** |
/** |
172 |
|
* Number of spaces between the text and the arrow icon. |
173 |
|
*/ |
174 |
|
private int defaultTextArrowIconGap = 10; |
175 |
|
|
176 |
|
/** |
177 |
* Creates a new BasicMenuItemUI object. |
* Creates a new BasicMenuItemUI object. |
178 |
*/ |
*/ |
179 |
public BasicMenuItemUI() |
public BasicMenuItemUI() |
181 |
mouseInputListener = createMouseInputListener(menuItem); |
mouseInputListener = createMouseInputListener(menuItem); |
182 |
menuDragMouseListener = createMenuDragMouseListener(menuItem); |
menuDragMouseListener = createMenuDragMouseListener(menuItem); |
183 |
menuKeyListener = createMenuKeyListener(menuItem); |
menuKeyListener = createMenuKeyListener(menuItem); |
184 |
propertyChangeListener = new PropertyChangeHandler(); |
itemListener = new ItemHandler(); |
185 |
} |
} |
186 |
|
|
187 |
/** |
/** |
333 |
m.getToolkit().getFontMetrics(acceleratorFont)); |
m.getToolkit().getFontMetrics(acceleratorFont)); |
334 |
|
|
335 |
// add width of accelerator's text |
// add width of accelerator's text |
336 |
d.width = d.width + rect.width + defaultAcceleratorLabelGap; |
d.width += rect.width + defaultAcceleratorLabelGap; |
337 |
|
|
338 |
// adjust the heigth of the preferred size if necessary |
// adjust the heigth of the preferred size if necessary |
339 |
if (d.height < rect.height) |
if (d.height < rect.height) |
350 |
|
|
351 |
if (arrowIcon != null && (c instanceof JMenu)) |
if (arrowIcon != null && (c instanceof JMenu)) |
352 |
{ |
{ |
353 |
d.width = d.width + arrowIcon.getIconWidth() + defaultTextIconGap; |
d.width = d.width + arrowIcon.getIconWidth() + defaultTextArrowIconGap; |
354 |
|
|
355 |
if (arrowIcon.getIconHeight() > d.height) |
if (arrowIcon.getIconHeight() > d.height) |
356 |
d.height = arrowIcon.getIconHeight(); |
d.height = arrowIcon.getIconHeight(); |
398 |
*/ |
*/ |
399 |
protected void installDefaults() |
protected void installDefaults() |
400 |
{ |
{ |
401 |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
String prefix = getPropertyPrefix(); |
402 |
|
LookAndFeel.installBorder(menuItem, prefix + ".border"); |
403 |
menuItem.setBackground(defaults.getColor("MenuItem.background")); |
LookAndFeel.installColorsAndFont(menuItem, prefix + ".background", |
404 |
menuItem.setBorder(defaults.getBorder("MenuItem.border")); |
prefix + ".foreground", prefix + ".font"); |
405 |
menuItem.setFont(defaults.getFont("MenuItem.font")); |
menuItem.setMargin(UIManager.getInsets(prefix + ".margin")); |
406 |
menuItem.setForeground(defaults.getColor("MenuItem.foreground")); |
acceleratorFont = UIManager.getFont(prefix + ".acceleratorFont"); |
407 |
menuItem.setMargin(defaults.getInsets("MenuItem.margin")); |
acceleratorForeground = UIManager.getColor(prefix + ".acceleratorForeground"); |
408 |
menuItem.setOpaque(true); |
acceleratorSelectionForeground = UIManager.getColor(prefix + ".acceleratorSelectionForeground"); |
409 |
acceleratorFont = defaults.getFont("MenuItem.acceleratorFont"); |
selectionBackground = UIManager.getColor(prefix + ".selectionBackground"); |
410 |
acceleratorForeground = defaults.getColor("MenuItem.acceleratorForeground"); |
selectionForeground = UIManager.getColor(prefix + ".selectionForeground"); |
411 |
acceleratorSelectionForeground = defaults.getColor("MenuItem.acceleratorSelectionForeground"); |
acceleratorDelimiter = UIManager.getString(prefix + ".acceleratorDelimiter"); |
412 |
selectionBackground = defaults.getColor("MenuItem.selectionBackground"); |
checkIcon = UIManager.getIcon(prefix + ".checkIcon"); |
413 |
selectionForeground = defaults.getColor("MenuItem.selectionForeground"); |
|
|
acceleratorDelimiter = defaults.getString("MenuItem.acceleratorDelimiter"); |
|
|
|
|
414 |
menuItem.setHorizontalTextPosition(SwingConstants.TRAILING); |
menuItem.setHorizontalTextPosition(SwingConstants.TRAILING); |
415 |
menuItem.setHorizontalAlignment(SwingConstants.LEADING); |
menuItem.setHorizontalAlignment(SwingConstants.LEADING); |
416 |
|
menuItem.setOpaque(true); |
417 |
} |
} |
418 |
|
|
419 |
/** |
/** |
433 |
menuItem.addMouseMotionListener(mouseInputListener); |
menuItem.addMouseMotionListener(mouseInputListener); |
434 |
menuItem.addMenuDragMouseListener(menuDragMouseListener); |
menuItem.addMenuDragMouseListener(menuDragMouseListener); |
435 |
menuItem.addMenuKeyListener(menuKeyListener); |
menuItem.addMenuKeyListener(menuKeyListener); |
436 |
menuItem.addPropertyChangeListener(propertyChangeListener); |
menuItem.addItemListener(itemListener); |
437 |
} |
} |
438 |
|
|
439 |
/** |
/** |
540 |
|
|
541 |
// Menu item is considered to be highlighted when it is selected. |
// Menu item is considered to be highlighted when it is selected. |
542 |
// But we don't want to paint the background of JCheckBoxMenuItems |
// But we don't want to paint the background of JCheckBoxMenuItems |
543 |
if ((m.isSelected() && checkIcon == null) || m.getModel().isArmed() |
ButtonModel mod = m.getModel(); |
544 |
|
if ((m.isSelected() && checkIcon == null) || (mod != null && |
545 |
|
mod.isArmed()) |
546 |
&& (m.getParent() instanceof MenuElement)) |
&& (m.getParent() instanceof MenuElement)) |
547 |
{ |
{ |
548 |
if (m.isContentAreaFilled()) |
if (m.isContentAreaFilled()) |
581 |
{ |
{ |
582 |
int width = arrowIcon.getIconWidth(); |
int width = arrowIcon.getIconWidth(); |
583 |
int height = arrowIcon.getIconHeight(); |
int height = arrowIcon.getIconHeight(); |
584 |
|
int offset = (vr.height - height) / 2; |
585 |
arrowIcon.paintIcon(m, g, vr.width - width + defaultTextIconGap, |
arrowIcon.paintIcon(m, g, vr.width - width, vr.y + offset); |
|
vr.y + 2); |
|
586 |
} |
} |
587 |
} |
} |
588 |
|
|
641 |
{ |
{ |
642 |
// Menu item is considered to be highlighted when it is selected. |
// Menu item is considered to be highlighted when it is selected. |
643 |
// But not if it's a JCheckBoxMenuItem |
// But not if it's a JCheckBoxMenuItem |
644 |
|
ButtonModel mod = menuItem.getModel(); |
645 |
if ((menuItem.isSelected() && checkIcon == null) |
if ((menuItem.isSelected() && checkIcon == null) |
646 |
|| menuItem.getModel().isArmed() |
|| (mod != null && mod.isArmed()) |
647 |
&& (menuItem.getParent() instanceof MenuElement)) |
&& (menuItem.getParent() instanceof MenuElement)) |
648 |
g.setColor(selectionForeground); |
g.setColor(selectionForeground); |
649 |
else |
else |
721 |
menuItem.removeMouseListener(mouseInputListener); |
menuItem.removeMouseListener(mouseInputListener); |
722 |
menuItem.removeMenuDragMouseListener(menuDragMouseListener); |
menuItem.removeMenuDragMouseListener(menuDragMouseListener); |
723 |
menuItem.removeMenuKeyListener(menuKeyListener); |
menuItem.removeMenuKeyListener(menuKeyListener); |
724 |
menuItem.removePropertyChangeListener(propertyChangeListener); |
menuItem.removeItemListener(itemListener); |
725 |
} |
} |
726 |
|
|
727 |
/** |
/** |
837 |
*/ |
*/ |
838 |
protected MouseInputHandler() |
protected MouseInputHandler() |
839 |
{ |
{ |
840 |
|
// Nothing to do here. |
841 |
} |
} |
842 |
|
|
843 |
/** |
/** |
952 |
/** |
/** |
953 |
* This class handles mouse dragged events. |
* This class handles mouse dragged events. |
954 |
*/ |
*/ |
955 |
protected class MenuDragMouseHandler implements MenuDragMouseListener |
private class MenuDragMouseHandler implements MenuDragMouseListener |
956 |
{ |
{ |
957 |
/** |
/** |
958 |
* Tbis method is invoked when mouse is dragged over the menu item. |
* Tbis method is invoked when mouse is dragged over the menu item. |
983 |
* Tbis method is invoked when mouse exits the menu item while it is being |
* Tbis method is invoked when mouse exits the menu item while it is being |
984 |
* dragged |
* dragged |
985 |
* |
* |
986 |
* @param e |
* @param e the MenuDragMouseEvent |
|
* The MenuDragMouseEvent |
|
987 |
*/ |
*/ |
988 |
public void menuDragMouseExited(MenuDragMouseEvent e) |
public void menuDragMouseExited(MenuDragMouseEvent e) |
989 |
{ |
{ |
990 |
|
// TODO: What should be done here, if anything? |
991 |
} |
} |
992 |
|
|
993 |
/** |
/** |
1013 |
* This class handles key events occuring when menu item is visible on the |
* This class handles key events occuring when menu item is visible on the |
1014 |
* screen. |
* screen. |
1015 |
*/ |
*/ |
1016 |
protected class MenuKeyHandler implements MenuKeyListener |
private class MenuKeyHandler implements MenuKeyListener |
1017 |
{ |
{ |
1018 |
/** |
/** |
1019 |
* This method is invoked when key has been pressed |
* This method is invoked when key has been pressed |
1023 |
*/ |
*/ |
1024 |
public void menuKeyPressed(MenuKeyEvent e) |
public void menuKeyPressed(MenuKeyEvent e) |
1025 |
{ |
{ |
1026 |
|
// TODO: What should be done here, if anything? |
1027 |
} |
} |
1028 |
|
|
1029 |
/** |
/** |
1034 |
*/ |
*/ |
1035 |
public void menuKeyReleased(MenuKeyEvent e) |
public void menuKeyReleased(MenuKeyEvent e) |
1036 |
{ |
{ |
1037 |
|
// TODO: What should be done here, if anything? |
1038 |
} |
} |
1039 |
|
|
1040 |
/** |
/** |
1046 |
*/ |
*/ |
1047 |
public void menuKeyTyped(MenuKeyEvent e) |
public void menuKeyTyped(MenuKeyEvent e) |
1048 |
{ |
{ |
1049 |
|
// TODO: What should be done here, if anything? |
1050 |
} |
} |
1051 |
} |
} |
1052 |
|
|
1053 |
/** |
/** |
1054 |
* Helper class that listens for changes to the properties of the {@link |
* Helper class that listens for item changes to the properties of the {@link |
1055 |
* JMenuItem}. |
* JMenuItem}. |
1056 |
*/ |
*/ |
1057 |
protected class PropertyChangeHandler implements PropertyChangeListener |
private class ItemHandler implements ItemListener |
1058 |
{ |
{ |
1059 |
/** |
/** |
1060 |
* This method is called when one of the menu item's properties change. |
* This method is called when one of the menu item changes. |
1061 |
* |
* |
1062 |
* @param evt A {@link PropertyChangeEvent}. |
* @param evt A {@link ItemEvent}. |
1063 |
*/ |
*/ |
1064 |
public void propertyChange(PropertyChangeEvent evt) |
public void itemStateChanged(ItemEvent evt) |
1065 |
{ |
{ |
1066 |
|
boolean state = false; |
1067 |
|
if (menuItem instanceof JCheckBoxMenuItem) |
1068 |
|
{ |
1069 |
|
if (evt.getStateChange() == ItemEvent.SELECTED) |
1070 |
|
state = true; |
1071 |
|
((JCheckBoxMenuItem) menuItem).setState(state); |
1072 |
|
} |
1073 |
menuItem.revalidate(); |
menuItem.revalidate(); |
1074 |
menuItem.repaint(); |
menuItem.repaint(); |
1075 |
} |
} |