Showing the changes to java/pkg/javax/swing/plaf/basic/BasicMenuItemUI.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,972 @@ | |||
| 1 | /* | ||
| 2 | * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. | ||
| 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
| 4 | * | ||
| 5 | * This code is free software; you can redistribute it and/or modify it | ||
| 6 | * under the terms of the GNU General Public License version 2 only, as | ||
| 7 | * published by the Free Software Foundation. Oracle designates this | ||
| 8 | * particular file as subject to the "Classpath" exception as provided | ||
| 9 | * by Oracle in the LICENSE file that accompanied this code. | ||
| 10 | * | ||
| 11 | * This code is distributed in the hope that it will be useful, but WITHOUT | ||
| 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
| 13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
| 14 | * version 2 for more details (a copy is included in the LICENSE file that | ||
| 15 | * accompanied this code). | ||
| 16 | * | ||
| 17 | * You should have received a copy of the GNU General Public License version | ||
| 18 | * 2 along with this work; if not, write to the Free Software Foundation, | ||
| 19 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
| 20 | * | ||
| 21 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
| 22 | * or visit www.oracle.com if you need additional information or have any | ||
| 23 | * questions. | ||
| 24 | */ | ||
| 25 | |||
| 26 | package javax.swing.plaf.basic; | ||
| 27 | |||
| 28 | import java.awt.*; | ||
| 29 | import java.awt.event.*; | ||
| 30 | import java.beans.PropertyChangeEvent; | ||
| 31 | import java.beans.PropertyChangeListener; | ||
| 32 | |||
| 33 | import javax.swing.*; | ||
| 34 | import javax.swing.event.*; | ||
| 35 | import javax.swing.plaf.*; | ||
| 36 | import javax.swing.text.View; | ||
| 37 | |||
| 38 | import sun.swing.*; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * BasicMenuItem implementation | ||
| 42 | * | ||
| 43 | * @author Georges Saab | ||
| 44 | * @author David Karlton | ||
| 45 | * @author Arnaud Weber | ||
| 46 | * @author Fredrik Lagerblad | ||
| 47 | */ | ||
| 48 | public class BasicMenuItemUI extends MenuItemUI | ||
| 49 | { | ||
| 50 | protected JMenuItem menuItem = null; | ||
| 51 | protected Color selectionBackground; | ||
| 52 | protected Color selectionForeground; | ||
| 53 | protected Color disabledForeground; | ||
| 54 | protected Color acceleratorForeground; | ||
| 55 | protected Color acceleratorSelectionForeground; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * Accelerator delimiter string, such as {@code '+'} in {@code 'Ctrl+C'}. | ||
| 59 | * @since 1.7 | ||
| 60 | */ | ||
| 61 | protected String acceleratorDelimiter; | ||
| 62 | |||
| 63 | protected int defaultTextIconGap; | ||
| 64 | protected Font acceleratorFont; | ||
| 65 | |||
| 66 | protected MouseInputListener mouseInputListener; | ||
| 67 | protected MenuDragMouseListener menuDragMouseListener; | ||
| 68 | protected MenuKeyListener menuKeyListener; | ||
| 69 | /** | ||
| 70 | * <code>PropertyChangeListener</code> returned from | ||
| 71 | * <code>createPropertyChangeListener</code>. You should not | ||
| 72 | * need to access this field, rather if you want to customize the | ||
| 73 | * <code>PropertyChangeListener</code> override | ||
| 74 | * <code>createPropertyChangeListener</code>. | ||
| 75 | * | ||
| 76 | * @since 1.6 | ||
| 77 | * @see #createPropertyChangeListener | ||
| 78 | */ | ||
| 79 | protected PropertyChangeListener propertyChangeListener; | ||
| 80 | // BasicMenuUI also uses this. | ||
| 81 | Handler handler; | ||
| 82 | |||
| 83 | protected Icon arrowIcon = null; | ||
| 84 | protected Icon checkIcon = null; | ||
| 85 | |||
| 86 | protected boolean oldBorderPainted; | ||
| 87 | |||
| 88 | /* diagnostic aids -- should be false for production builds. */ | ||
| 89 | private static final boolean TRACE = false; // trace creates and disposes | ||
| 90 | |||
| 91 | private static final boolean VERBOSE = false; // show reuse hits/misses | ||
| 92 | private static final boolean DEBUG = false; // show bad params, misc. | ||
| 93 | |||
| 94 | static void loadActionMap(LazyActionMap map) { | ||
| 95 | // NOTE: BasicMenuUI also calls into this method. | ||
| 96 | map.put(new Actions(Actions.CLICK)); | ||
| 97 | BasicLookAndFeel.installAudioActionMap(map); | ||
| 98 | } | ||
| 99 | |||
| 100 | public static ComponentUI createUI(JComponent c) { | ||
| 101 | return new BasicMenuItemUI(); | ||
| 102 | } | ||
| 103 | |||
| 104 | public void installUI(JComponent c) { | ||
| 105 | menuItem = (JMenuItem) c; | ||
| 106 | |||
| 107 | installDefaults(); | ||
| 108 | installComponents(menuItem); | ||
| 109 | installListeners(); | ||
| 110 | installKeyboardActions(); | ||
| 111 | } | ||
| 112 | |||
| 113 | |||
| 114 | protected void installDefaults() { | ||
| 115 | String prefix = getPropertyPrefix(); | ||
| 116 | |||
| 117 | acceleratorFont = UIManager.getFont("MenuItem.acceleratorFont"); | ||
| 118 | // use default if missing so that BasicMenuItemUI can be used in other | ||
| 119 | // LAFs like Nimbus | ||
| 120 | if (acceleratorFont == null) { | ||
| 121 | acceleratorFont = UIManager.getFont("MenuItem.font"); | ||
| 122 | } | ||
| 123 | |||
| 124 | Object opaque = UIManager.get(getPropertyPrefix() + ".opaque"); | ||
| 125 | if (opaque != null) { | ||
| 126 | LookAndFeel.installProperty(menuItem, "opaque", opaque); | ||
| 127 | } | ||
| 128 | else { | ||
| 129 | LookAndFeel.installProperty(menuItem, "opaque", Boolean.TRUE); | ||
| 130 | } | ||
| 131 | if(menuItem.getMargin() == null || | ||
| 132 | (menuItem.getMargin() instanceof UIResource)) { | ||
| 133 | menuItem.setMargin(UIManager.getInsets(prefix + ".margin")); | ||
| 134 | } | ||
| 135 | |||
| 136 | LookAndFeel.installProperty(menuItem, "iconTextGap", Integer.valueOf(4)); | ||
| 137 | defaultTextIconGap = menuItem.getIconTextGap(); | ||
| 138 | |||
| 139 | LookAndFeel.installBorder(menuItem, prefix + ".border"); | ||
| 140 | oldBorderPainted = menuItem.isBorderPainted(); | ||
| 141 | LookAndFeel.installProperty(menuItem, "borderPainted", | ||
| 142 | UIManager.getBoolean(prefix + ".borderPainted")); | ||
| 143 | LookAndFeel.installColorsAndFont(menuItem, | ||
| 144 | prefix + ".background", | ||
| 145 | prefix + ".foreground", | ||
| 146 | prefix + ".font"); | ||
| 147 | |||
| 148 | // MenuItem specific defaults | ||
| 149 | if (selectionBackground == null || | ||
| 150 | selectionBackground instanceof UIResource) { | ||
| 151 | selectionBackground = | ||
| 152 | UIManager.getColor(prefix + ".selectionBackground"); | ||
| 153 | } | ||
| 154 | if (selectionForeground == null || | ||
| 155 | selectionForeground instanceof UIResource) { | ||
| 156 | selectionForeground = | ||
| 157 | UIManager.getColor(prefix + ".selectionForeground"); | ||
| 158 | } | ||
| 159 | if (disabledForeground == null || | ||
| 160 | disabledForeground instanceof UIResource) { | ||
| 161 | disabledForeground = | ||
| 162 | UIManager.getColor(prefix + ".disabledForeground"); | ||
| 163 | } | ||
| 164 | if (acceleratorForeground == null || | ||
| 165 | acceleratorForeground instanceof UIResource) { | ||
| 166 | acceleratorForeground = | ||
| 167 | UIManager.getColor(prefix + ".acceleratorForeground"); | ||
| 168 | } | ||
| 169 | if (acceleratorSelectionForeground == null || | ||
| 170 | acceleratorSelectionForeground instanceof UIResource) { | ||
| 171 | acceleratorSelectionForeground = | ||
| 172 | UIManager.getColor(prefix + ".acceleratorSelectionForeground"); | ||
| 173 | } | ||
| 174 | // Get accelerator delimiter | ||
| 175 | acceleratorDelimiter = | ||
| 176 | UIManager.getString("MenuItem.acceleratorDelimiter"); | ||
| 177 | if (acceleratorDelimiter == null) { acceleratorDelimiter = "+"; } | ||
| 178 | // Icons | ||
| 179 | if (arrowIcon == null || | ||
| 180 | arrowIcon instanceof UIResource) { | ||
| 181 | arrowIcon = UIManager.getIcon(prefix + ".arrowIcon"); | ||
| 182 | } | ||
| 183 | if (checkIcon == null || | ||
| 184 | checkIcon instanceof UIResource) { | ||
| 185 | checkIcon = UIManager.getIcon(prefix + ".checkIcon"); | ||
| 186 | //In case of column layout, .checkIconFactory is defined for this UI, | ||
| 187 | //the icon is compatible with it and useCheckAndArrow() is true, | ||
| 188 | //then the icon is handled by the checkIcon. | ||
| 189 | boolean isColumnLayout = MenuItemLayoutHelper.isColumnLayout( | ||
| 190 | BasicGraphicsUtils.isLeftToRight(menuItem), menuItem); | ||
| 191 | if (isColumnLayout) { | ||
| 192 | MenuItemCheckIconFactory iconFactory = | ||
| 193 | (MenuItemCheckIconFactory) UIManager.get(prefix | ||
| 194 | + ".checkIconFactory"); | ||
| 195 | if (iconFactory != null | ||
| 196 | && MenuItemLayoutHelper.useCheckAndArrow(menuItem) | ||
| 197 | && iconFactory.isCompatible(checkIcon, prefix)) { | ||
| 198 | checkIcon = iconFactory.getIcon(menuItem); | ||
| 199 | } | ||
| 200 | } | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | /** | ||
| 205 | * @since 1.3 | ||
| 206 | */ | ||
| 207 | protected void installComponents(JMenuItem menuItem){ | ||
| 208 | BasicHTML.updateRenderer(menuItem, menuItem.getText()); | ||
| 209 | } | ||
| 210 | |||
| 211 | protected String getPropertyPrefix() { | ||
| 212 | return "MenuItem"; | ||
| 213 | } | ||
| 214 | |||
| 215 | protected void installListeners() { | ||
| 216 | if ((mouseInputListener = createMouseInputListener(menuItem)) != null) { | ||
| 217 | menuItem.addMouseListener(mouseInputListener); | ||
| 218 | menuItem.addMouseMotionListener(mouseInputListener); | ||
| 219 | } | ||
| 220 | if ((menuDragMouseListener = createMenuDragMouseListener(menuItem)) != null) { | ||
| 221 | menuItem.addMenuDragMouseListener(menuDragMouseListener); | ||
| 222 | } | ||
| 223 | if ((menuKeyListener = createMenuKeyListener(menuItem)) != null) { | ||
| 224 | menuItem.addMenuKeyListener(menuKeyListener); | ||
| 225 | } | ||
| 226 | if ((propertyChangeListener = createPropertyChangeListener(menuItem)) != null) { | ||
| 227 | menuItem.addPropertyChangeListener(propertyChangeListener); | ||
| 228 | } | ||
| 229 | } | ||
| 230 | |||
| 231 | protected void installKeyboardActions() { | ||
| 232 | installLazyActionMap(); | ||
| 233 | updateAcceleratorBinding(); | ||
| 234 | } | ||
| 235 | |||
| 236 | void installLazyActionMap() { | ||
| 237 | LazyActionMap.installLazyActionMap(menuItem, BasicMenuItemUI.class, | ||
| 238 | getPropertyPrefix() + ".actionMap"); | ||
| 239 | } | ||
| 240 | |||
| 241 | public void uninstallUI(JComponent c) { | ||
| 242 | menuItem = (JMenuItem)c; | ||
| 243 | uninstallDefaults(); | ||
| 244 | uninstallComponents(menuItem); | ||
| 245 | uninstallListeners(); | ||
| 246 | uninstallKeyboardActions(); | ||
| 247 | MenuItemLayoutHelper.clearUsedParentClientProperties(menuItem); | ||
| 248 | menuItem = null; | ||
| 249 | } | ||
| 250 | |||
| 251 | |||
| 252 | protected void uninstallDefaults() { | ||
| 253 | LookAndFeel.uninstallBorder(menuItem); | ||
| 254 | LookAndFeel.installProperty(menuItem, "borderPainted", oldBorderPainted); | ||
| 255 | if (menuItem.getMargin() instanceof UIResource) | ||
| 256 | menuItem.setMargin(null); | ||
| 257 | if (arrowIcon instanceof UIResource) | ||
| 258 | arrowIcon = null; | ||
| 259 | if (checkIcon instanceof UIResource) | ||
| 260 | checkIcon = null; | ||
| 261 | } | ||
| 262 | |||
| 263 | /** | ||
| 264 | * @since 1.3 | ||
| 265 | */ | ||
| 266 | protected void uninstallComponents(JMenuItem menuItem){ | ||
| 267 | BasicHTML.updateRenderer(menuItem, ""); | ||
| 268 | } | ||
| 269 | |||
| 270 | protected void uninstallListeners() { | ||
| 271 | if (mouseInputListener != null) { | ||
| 272 | menuItem.removeMouseListener(mouseInputListener); | ||
| 273 | menuItem.removeMouseMotionListener(mouseInputListener); | ||
| 274 | } | ||
| 275 | if (menuDragMouseListener != null) { | ||
| 276 | menuItem.removeMenuDragMouseListener(menuDragMouseListener); | ||
| 277 | } | ||
| 278 | if (menuKeyListener != null) { | ||
| 279 | menuItem.removeMenuKeyListener(menuKeyListener); | ||
| 280 | } | ||
| 281 | if (propertyChangeListener != null) { | ||
| 282 | menuItem.removePropertyChangeListener(propertyChangeListener); | ||
| 283 | } | ||
| 284 | |||
| 285 | mouseInputListener = null; | ||
| 286 | menuDragMouseListener = null; | ||
| 287 | menuKeyListener = null; | ||
| 288 | propertyChangeListener = null; | ||
| 289 | handler = null; | ||
| 290 | } | ||
| 291 | |||
| 292 | protected void uninstallKeyboardActions() { | ||
| 293 | SwingUtilities.replaceUIActionMap(menuItem, null); | ||
| 294 | SwingUtilities.replaceUIInputMap(menuItem, JComponent. | ||
| 295 | WHEN_IN_FOCUSED_WINDOW, null); | ||
| 296 | } | ||
| 297 | |||
| 298 | protected MouseInputListener createMouseInputListener(JComponent c) { | ||
| 299 | return getHandler(); | ||
| 300 | } | ||
| 301 | |||
| 302 | protected MenuDragMouseListener createMenuDragMouseListener(JComponent c) { | ||
| 303 | return getHandler(); | ||
| 304 | } | ||
| 305 | |||
| 306 | protected MenuKeyListener createMenuKeyListener(JComponent c) { | ||
| 307 | return null; | ||
| 308 | } | ||
| 309 | |||
| 310 | /** | ||
| 311 | * Creates a <code>PropertyChangeListener</code> which will be added to | ||
| 312 | * the menu item. | ||
| 313 | * If this method returns null then it will not be added to the menu item. | ||
| 314 | * | ||
| 315 | * @return an instance of a <code>PropertyChangeListener</code> or null | ||
| 316 | * @since 1.6 | ||
| 317 | */ | ||
| 318 | protected PropertyChangeListener | ||
| 319 | createPropertyChangeListener(JComponent c) { | ||
| 320 | return getHandler(); | ||
| 321 | } | ||
| 322 | |||
| 323 | Handler getHandler() { | ||
| 324 | if (handler == null) { | ||
| 325 | handler = new Handler(); | ||
| 326 | } | ||
| 327 | return handler; | ||
| 328 | } | ||
| 329 | |||
| 330 | InputMap createInputMap(int condition) { | ||
| 331 | if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) { | ||
| 332 | return new ComponentInputMapUIResource(menuItem); | ||
| 333 | } | ||
| 334 | return null; | ||
| 335 | } | ||
| 336 | |||
| 337 | void updateAcceleratorBinding() { | ||
| 338 | KeyStroke accelerator = menuItem.getAccelerator(); | ||
| 339 | InputMap windowInputMap = SwingUtilities.getUIInputMap( | ||
| 340 | menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW); | ||
| 341 | |||
| 342 | if (windowInputMap != null) { | ||
| 343 | windowInputMap.clear(); | ||
| 344 | } | ||
| 345 | if (accelerator != null) { | ||
| 346 | if (windowInputMap == null) { | ||
| 347 | windowInputMap = createInputMap(JComponent. | ||
| 348 | WHEN_IN_FOCUSED_WINDOW); | ||
| 349 | SwingUtilities.replaceUIInputMap(menuItem, | ||
| 350 | JComponent.WHEN_IN_FOCUSED_WINDOW, windowInputMap); | ||
| 351 | } | ||
| 352 | windowInputMap.put(accelerator, "doClick"); | ||
| 353 | } | ||
| 354 | } | ||
| 355 | |||
| 356 | public Dimension getMinimumSize(JComponent c) { | ||
| 357 | Dimension d = null; | ||
| 358 | View v = (View) c.getClientProperty(BasicHTML.propertyKey); | ||
| 359 | if (v != null) { | ||
| 360 | d = getPreferredSize(c); | ||
| 361 | d.width -= v.getPreferredSpan(View.X_AXIS) - v.getMinimumSpan(View.X_AXIS); | ||
| 362 | } | ||
| 363 | return d; | ||
| 364 | } | ||
| 365 | |||
| 366 | public Dimension getPreferredSize(JComponent c) { | ||
| 367 | return getPreferredMenuItemSize(c, | ||
| 368 | checkIcon, | ||
| 369 | arrowIcon, | ||
| 370 | defaultTextIconGap); | ||
| 371 | } | ||
| 372 | |||
| 373 | public Dimension getMaximumSize(JComponent c) { | ||
| 374 | Dimension d = null; | ||
| 375 | View v = (View) c.getClientProperty(BasicHTML.propertyKey); | ||
| 376 | if (v != null) { | ||
| 377 | d = getPreferredSize(c); | ||
| 378 | d.width += v.getMaximumSpan(View.X_AXIS) - v.getPreferredSpan(View.X_AXIS); | ||
| 379 | } | ||
| 380 | return d; | ||
| 381 | } | ||
| 382 | |||
| 383 | protected Dimension getPreferredMenuItemSize(JComponent c, | ||
| 384 | Icon checkIcon, | ||
| 385 | Icon arrowIcon, | ||
| 386 | int defaultTextIconGap) { | ||
| 387 | |||
| 388 | // The method also determines the preferred width of the | ||
| 389 | // parent popup menu (through DefaultMenuLayout class). | ||
| 390 | // The menu width equals to the maximal width | ||
| 391 | // among child menu items. | ||
| 392 | |||
| 393 | // Menu item width will be a sum of the widest check icon, label, | ||
| 394 | // arrow icon and accelerator text among neighbor menu items. | ||
| 395 | // For the latest menu item we will know the maximal widths exactly. | ||
| 396 | // It will be the widest menu item and it will determine | ||
| 397 | // the width of the parent popup menu. | ||
| 398 | |||
| 399 | // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | ||
| 400 | // There is a conceptual problem: if user sets preferred size manually | ||
| 401 | // for a menu item, this method won't be called for it | ||
| 402 | // (see JComponent.getPreferredSize()), | ||
| 403 | // maximal widths won't be calculated, other menu items won't be able | ||
| 404 | // to take them into account and will be layouted in such a way, | ||
| 405 | // as there is no the item with manual preferred size. | ||
| 406 | // But after the first paint() method call, all maximal widths | ||
| 407 | // will be correctly calculated and layout of some menu items | ||
| 408 | // can be changed. For example, it can cause a shift of | ||
| 409 | // the icon and text when user points a menu item by mouse. | ||
| 410 | |||
| 411 | JMenuItem mi = (JMenuItem) c; | ||
| 412 | MenuItemLayoutHelper lh = new MenuItemLayoutHelper(mi, checkIcon, | ||
| 413 | arrowIcon, MenuItemLayoutHelper.createMaxRect(), defaultTextIconGap, | ||
| 414 | acceleratorDelimiter, BasicGraphicsUtils.isLeftToRight(mi), | ||
| 415 | mi.getFont(), acceleratorFont, | ||
| 416 | MenuItemLayoutHelper.useCheckAndArrow(menuItem), | ||
| 417 | getPropertyPrefix()); | ||
| 418 | |||
| 419 | Dimension result = new Dimension(); | ||
| 420 | |||
| 421 | // Calculate the result width | ||
| 422 | result.width = lh.getLeadingGap(); | ||
| 423 | MenuItemLayoutHelper.addMaxWidth(lh.getCheckSize(), | ||
| 424 | lh.getAfterCheckIconGap(), result); | ||
| 425 | // Take into account mimimal text offset. | ||
| 426 | if ((!lh.isTopLevelMenu()) | ||
| 427 | && (lh.getMinTextOffset() > 0) | ||
| 428 | && (result.width < lh.getMinTextOffset())) { | ||
| 429 | result.width = lh.getMinTextOffset(); | ||
| 430 | } | ||
| 431 | MenuItemLayoutHelper.addMaxWidth(lh.getLabelSize(), lh.getGap(), result); | ||
| 432 | MenuItemLayoutHelper.addMaxWidth(lh.getAccSize(), lh.getGap(), result); | ||
| 433 | MenuItemLayoutHelper.addMaxWidth(lh.getArrowSize(), lh.getGap(), result); | ||
| 434 | |||
| 435 | // Calculate the result height | ||
| 436 | result.height = MenuItemLayoutHelper.max(lh.getCheckSize().getHeight(), | ||
| 437 | lh.getLabelSize().getHeight(), lh.getAccSize().getHeight(), | ||
| 438 | lh.getArrowSize().getHeight()); | ||
| 439 | |||
| 440 | // Take into account menu item insets | ||
| 441 | Insets insets = lh.getMenuItem().getInsets(); | ||
| 442 | if(insets != null) { | ||
| 443 | result.width += insets.left + insets.right; | ||
| 444 | result.height += insets.top + insets.bottom; | ||
| 445 | } | ||
| 446 | |||
| 447 | // if the width is even, bump it up one. This is critical | ||
| 448 | // for the focus dash line to draw properly | ||
| 449 | if(result.width%2 == 0) { | ||
| 450 | result.width++; | ||
| 451 | } | ||
| 452 | |||
| 453 | // if the height is even, bump it up one. This is critical | ||
| 454 | // for the text to center properly | ||
| 455 | if(result.height%2 == 0 | ||
| 456 | && Boolean.TRUE != | ||
| 457 | UIManager.get(getPropertyPrefix() + ".evenHeight")) { | ||
| 458 | result.height++; | ||
| 459 | } | ||
| 460 | |||
| 461 | return result; | ||
| 462 | } | ||
| 463 | |||
| 464 | /** | ||
| 465 | * We draw the background in paintMenuItem() | ||
| 466 | * so override update (which fills the background of opaque | ||
| 467 | * components by default) to just call paint(). | ||
| 468 | * | ||
| 469 | */ | ||
| 470 | public void update(Graphics g, JComponent c) { | ||
| 471 | paint(g, c); | ||
| 472 | } | ||
| 473 | |||
| 474 | public void paint(Graphics g, JComponent c) { | ||
| 475 | paintMenuItem(g, c, checkIcon, arrowIcon, | ||
| 476 | selectionBackground, selectionForeground, | ||
| 477 | defaultTextIconGap); | ||
| 478 | } | ||
| 479 | |||
| 480 | protected void paintMenuItem(Graphics g, JComponent c, | ||
| 481 | Icon checkIcon, Icon arrowIcon, | ||
| 482 | Color background, Color foreground, | ||
| 483 | int defaultTextIconGap) { | ||
| 484 | // Save original graphics font and color | ||
| 485 | Font holdf = g.getFont(); | ||
| 486 | Color holdc = g.getColor(); | ||
| 487 | |||
| 488 | JMenuItem mi = (JMenuItem) c; | ||
| 489 | g.setFont(mi.getFont()); | ||
| 490 | |||
| 491 | Rectangle viewRect = new Rectangle(0, 0, mi.getWidth(), mi.getHeight()); | ||
| 492 | applyInsets(viewRect, mi.getInsets()); | ||
| 493 | |||
| 494 | MenuItemLayoutHelper lh = new MenuItemLayoutHelper(mi, checkIcon, | ||
| 495 | arrowIcon, viewRect, defaultTextIconGap, acceleratorDelimiter, | ||
| 496 | BasicGraphicsUtils.isLeftToRight(mi), mi.getFont(), | ||
| 497 | acceleratorFont, MenuItemLayoutHelper.useCheckAndArrow(menuItem), | ||
| 498 | getPropertyPrefix()); | ||
| 499 | MenuItemLayoutHelper.LayoutResult lr = lh.layoutMenuItem(); | ||
| 500 | |||
| 501 | paintBackground(g, mi, background); | ||
| 502 | paintCheckIcon(g, lh, lr, holdc, foreground); | ||
| 503 | paintIcon(g, lh, lr, holdc); | ||
| 504 | paintText(g, lh, lr); | ||
| 505 | paintAccText(g, lh, lr); | ||
| 506 | paintArrowIcon(g, lh, lr, foreground); | ||
| 507 | |||
| 508 | // Restore original graphics font and color | ||
| 509 | g.setColor(holdc); | ||
| 510 | g.setFont(holdf); | ||
| 511 | } | ||
| 512 | |||
| 513 | private void paintIcon(Graphics g, MenuItemLayoutHelper lh, | ||
| 514 | MenuItemLayoutHelper.LayoutResult lr, Color holdc) { | ||
| 515 | if (lh.getIcon() != null) { | ||
| 516 | Icon icon; | ||
| 517 | ButtonModel model = lh.getMenuItem().getModel(); | ||
| 518 | if (!model.isEnabled()) { | ||
| 519 | icon = lh.getMenuItem().getDisabledIcon(); | ||
| 520 | } else if (model.isPressed() && model.isArmed()) { | ||
| 521 | icon = lh.getMenuItem().getPressedIcon(); | ||
| 522 | if (icon == null) { | ||
| 523 | // Use default icon | ||
| 524 | icon = lh.getMenuItem().getIcon(); | ||
| 525 | } | ||
| 526 | } else { | ||
| 527 | icon = lh.getMenuItem().getIcon(); | ||
| 528 | } | ||
| 529 | |||
| 530 | if (icon != null) { | ||
| 531 | icon.paintIcon(lh.getMenuItem(), g, lr.getIconRect().x, | ||
| 532 | lr.getIconRect().y); | ||
| 533 | g.setColor(holdc); | ||
| 534 | } | ||
| 535 | } | ||
| 536 | } | ||
| 537 | |||
| 538 | private void paintCheckIcon(Graphics g, MenuItemLayoutHelper lh, | ||
| 539 | MenuItemLayoutHelper.LayoutResult lr, | ||
| 540 | Color holdc, Color foreground) { | ||
| 541 | if (lh.getCheckIcon() != null) { | ||
| 542 | ButtonModel model = lh.getMenuItem().getModel(); | ||
| 543 | if (model.isArmed() || (lh.getMenuItem() instanceof JMenu | ||
| 544 | && model.isSelected())) { | ||
| 545 | g.setColor(foreground); | ||
| 546 | } else { | ||
| 547 | g.setColor(holdc); | ||
| 548 | } | ||
| 549 | if (lh.useCheckAndArrow()) { | ||
| 550 | lh.getCheckIcon().paintIcon(lh.getMenuItem(), g, | ||
| 551 | lr.getCheckRect().x, lr.getCheckRect().y); | ||
| 552 | } | ||
| 553 | g.setColor(holdc); | ||
| 554 | } | ||
| 555 | } | ||
| 556 | |||
| 557 | private void paintAccText(Graphics g, MenuItemLayoutHelper lh, | ||
| 558 | MenuItemLayoutHelper.LayoutResult lr) { | ||
| 559 | if (!lh.getAccText().equals("")) { | ||
| 560 | ButtonModel model = lh.getMenuItem().getModel(); | ||
| 561 | g.setFont(lh.getAccFontMetrics().getFont()); | ||
| 562 | if (!model.isEnabled()) { | ||
| 563 | // *** paint the accText disabled | ||
| 564 | if (disabledForeground != null) { | ||
| 565 | g.setColor(disabledForeground); | ||
| 566 | SwingUtilities2.drawString(lh.getMenuItem(), g, | ||
| 567 | lh.getAccText(), lr.getAccRect().x, | ||
| 568 | lr.getAccRect().y + lh.getAccFontMetrics().getAscent()); | ||
| 569 | } else { | ||
| 570 | g.setColor(lh.getMenuItem().getBackground().brighter()); | ||
| 571 | SwingUtilities2.drawString(lh.getMenuItem(), g, | ||
| 572 | lh.getAccText(), lr.getAccRect().x, | ||
| 573 | lr.getAccRect().y + lh.getAccFontMetrics().getAscent()); | ||
| 574 | g.setColor(lh.getMenuItem().getBackground().darker()); | ||
| 575 | SwingUtilities2.drawString(lh.getMenuItem(), g, | ||
| 576 | lh.getAccText(), lr.getAccRect().x - 1, | ||
| 577 | lr.getAccRect().y + lh.getFontMetrics().getAscent() - 1); | ||
| 578 | } | ||
| 579 | } else { | ||
| 580 | // *** paint the accText normally | ||
| 581 | if (model.isArmed() | ||
| 582 | || (lh.getMenuItem() instanceof JMenu | ||
| 583 | && model.isSelected())) { | ||
| 584 | g.setColor(acceleratorSelectionForeground); | ||
| 585 | } else { | ||
| 586 | g.setColor(acceleratorForeground); | ||
| 587 | } | ||
| 588 | SwingUtilities2.drawString(lh.getMenuItem(), g, lh.getAccText(), | ||
| 589 | lr.getAccRect().x, lr.getAccRect().y + | ||
| 590 | lh.getAccFontMetrics().getAscent()); | ||
| 591 | } | ||
| 592 | } | ||
| 593 | } | ||
| 594 | |||
| 595 | private void paintText(Graphics g, MenuItemLayoutHelper lh, | ||
| 596 | MenuItemLayoutHelper.LayoutResult lr) { | ||
| 597 | if (!lh.getText().equals("")) { | ||
| 598 | if (lh.getHtmlView() != null) { | ||
| 599 | // Text is HTML | ||
| 600 | lh.getHtmlView().paint(g, lr.getTextRect()); | ||
| 601 | } else { | ||
| 602 | // Text isn't HTML | ||
| 603 | paintText(g, lh.getMenuItem(), lr.getTextRect(), lh.getText()); | ||
| 604 | } | ||
| 605 | } | ||
| 606 | } | ||
| 607 | |||
| 608 | private void paintArrowIcon(Graphics g, MenuItemLayoutHelper lh, | ||
| 609 | MenuItemLayoutHelper.LayoutResult lr, | ||
| 610 | Color foreground) { | ||
| 611 | if (lh.getArrowIcon() != null) { | ||
| 612 | ButtonModel model = lh.getMenuItem().getModel(); | ||
| 613 | if (model.isArmed() || (lh.getMenuItem() instanceof JMenu | ||
| 614 | && model.isSelected())) { | ||
| 615 | g.setColor(foreground); | ||
| 616 | } | ||
| 617 | if (lh.useCheckAndArrow()) { | ||
| 618 | lh.getArrowIcon().paintIcon(lh.getMenuItem(), g, | ||
| 619 | lr.getArrowRect().x, lr.getArrowRect().y); | ||
| 620 | } | ||
| 621 | } | ||
| 622 | } | ||
| 623 | |||
| 624 | private void applyInsets(Rectangle rect, Insets insets) { | ||
| 625 | if(insets != null) { | ||
| 626 | rect.x += insets.left; | ||
| 627 | rect.y += insets.top; | ||
| 628 | rect.width -= (insets.right + rect.x); | ||
| 629 | rect.height -= (insets.bottom + rect.y); | ||
| 630 | } | ||
| 631 | } | ||
| 632 | |||
| 633 | /** | ||
| 634 | * Draws the background of the menu item. | ||
| 635 | * | ||
| 636 | * @param g the paint graphics | ||
| 637 | * @param menuItem menu item to be painted | ||
| 638 | * @param bgColor selection background color | ||
| 639 | * @since 1.4 | ||
| 640 | */ | ||
| 641 | protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { | ||
| 642 | ButtonModel model = menuItem.getModel(); | ||
| 643 | Color oldColor = g.getColor(); | ||
| 644 | int menuWidth = menuItem.getWidth(); | ||
| 645 | int menuHeight = menuItem.getHeight(); | ||
| 646 | |||
| 647 | if(menuItem.isOpaque()) { | ||
| 648 | if (model.isArmed()|| (menuItem instanceof JMenu && model.isSelected())) { | ||
| 649 | g.setColor(bgColor); | ||
| 650 | g.fillRect(0,0, menuWidth, menuHeight); | ||
| 651 | } else { | ||
| 652 | g.setColor(menuItem.getBackground()); | ||
| 653 | g.fillRect(0,0, menuWidth, menuHeight); | ||
| 654 | } | ||
| 655 | g.setColor(oldColor); | ||
| 656 | } | ||
| 657 | else if (model.isArmed() || (menuItem instanceof JMenu && | ||
| 658 | model.isSelected())) { | ||
| 659 | g.setColor(bgColor); | ||
| 660 | g.fillRect(0,0, menuWidth, menuHeight); | ||
| 661 | g.setColor(oldColor); | ||
| 662 | } | ||
| 663 | } | ||
| 664 | |||
| 665 | /** | ||
| 666 | * Renders the text of the current menu item. | ||
| 667 | * <p> | ||
| 668 | * @param g graphics context | ||
| 669 | * @param menuItem menu item to render | ||
| 670 | * @param textRect bounding rectangle for rendering the text | ||
| 671 | * @param text string to render | ||
| 672 | * @since 1.4 | ||
| 673 | */ | ||
| 674 | protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect, String text) { | ||
| 675 | ButtonModel model = menuItem.getModel(); | ||
| 676 | FontMetrics fm = SwingUtilities2.getFontMetrics(menuItem, g); | ||
| 677 | int mnemIndex = menuItem.getDisplayedMnemonicIndex(); | ||
| 678 | |||
| 679 | if(!model.isEnabled()) { | ||
| 680 | // *** paint the text disabled | ||
| 681 | if ( UIManager.get("MenuItem.disabledForeground") instanceof Color ) { | ||
| 682 | g.setColor( UIManager.getColor("MenuItem.disabledForeground") ); | ||
| 683 | SwingUtilities2.drawStringUnderlineCharAt(menuItem, g,text, | ||
| 684 | mnemIndex, textRect.x, textRect.y + fm.getAscent()); | ||
| 685 | } else { | ||
| 686 | g.setColor(menuItem.getBackground().brighter()); | ||
| 687 | SwingUtilities2.drawStringUnderlineCharAt(menuItem, g, text, | ||
| 688 | mnemIndex, textRect.x, textRect.y + fm.getAscent()); | ||
| 689 | g.setColor(menuItem.getBackground().darker()); | ||
| 690 | SwingUtilities2.drawStringUnderlineCharAt(menuItem, g,text, | ||
| 691 | mnemIndex, textRect.x - 1, textRect.y + | ||
| 692 | fm.getAscent() - 1); | ||
| 693 | } | ||
| 694 | } else { | ||
| 695 | // *** paint the text normally | ||
| 696 | if (model.isArmed()|| (menuItem instanceof JMenu && model.isSelected())) { | ||
| 697 | g.setColor(selectionForeground); // Uses protected field. | ||
| 698 | } | ||
| 699 | SwingUtilities2.drawStringUnderlineCharAt(menuItem, g,text, | ||
| 700 | mnemIndex, textRect.x, textRect.y + fm.getAscent()); | ||
| 701 | } | ||
| 702 | } | ||
| 703 | |||
| 704 | public MenuElement[] getPath() { | ||
| 705 | MenuSelectionManager m = MenuSelectionManager.defaultManager(); | ||
| 706 | MenuElement oldPath[] = m.getSelectedPath(); | ||
| 707 | MenuElement newPath[]; | ||
| 708 | int i = oldPath.length; | ||
| 709 | if (i == 0) | ||
| 710 | return new MenuElement[0]; | ||
| 711 | Component parent = menuItem.getParent(); | ||
| 712 | if (oldPath[i-1].getComponent() == parent) { | ||
| 713 | // The parent popup menu is the last so far | ||
| 714 | newPath = new MenuElement[i+1]; | ||
| 715 | System.arraycopy(oldPath, 0, newPath, 0, i); | ||
| 716 | newPath[i] = menuItem; | ||
| 717 | } else { | ||
| 718 | // A sibling menuitem is the current selection | ||
| 719 | // | ||
| 720 | // This probably needs to handle 'exit submenu into | ||
| 721 | // a menu item. Search backwards along the current | ||
| 722 | // selection until you find the parent popup menu, | ||
| 723 | // then copy up to that and add yourself... | ||
| 724 | int j; | ||
| 725 | for (j = oldPath.length-1; j >= 0; j--) { | ||
| 726 | if (oldPath[j].getComponent() == parent) | ||
| 727 | break; | ||
| 728 | } | ||
| 729 | newPath = new MenuElement[j+2]; | ||
| 730 | System.arraycopy(oldPath, 0, newPath, 0, j+1); | ||
| 731 | newPath[j+1] = menuItem; | ||
| 732 | /* | ||
| 733 | System.out.println("Sibling condition -- "); | ||
| 734 | System.out.println("Old array : "); | ||
| 735 | printMenuElementArray(oldPath, false); | ||
| 736 | System.out.println("New array : "); | ||
| 737 | printMenuElementArray(newPath, false); | ||
| 738 | */ | ||
| 739 | } | ||
| 740 | return newPath; | ||
| 741 | } | ||
| 742 | |||
| 743 | void printMenuElementArray(MenuElement path[], boolean dumpStack) { | ||
| 744 | System.out.println("Path is("); | ||
| 745 | int i, j; | ||
| 746 | for(i=0,j=path.length; i<j ;i++){ | ||
| 747 | for (int k=0; k<=i; k++) | ||
| 748 | System.out.print(" "); | ||
| 749 | MenuElement me = path[i]; | ||
| 750 | if(me instanceof JMenuItem) | ||
| 751 | System.out.println(((JMenuItem)me).getText() + ", "); | ||
| 752 | else if (me == null) | ||
| 753 | System.out.println("NULL , "); | ||
| 754 | else | ||
| 755 | System.out.println("" + me + ", "); | ||
| 756 | } | ||
| 757 | System.out.println(")"); | ||
| 758 | |||
| 759 | if (dumpStack == true) | ||
| 760 | Thread.dumpStack(); | ||
| 761 | } | ||
| 762 | protected class MouseInputHandler implements MouseInputListener { | ||
| 763 | // NOTE: This class exists only for backward compatability. All | ||
| 764 | // its functionality has been moved into Handler. If you need to add | ||
| 765 | // new functionality add it to the Handler, but make sure this | ||
| 766 | // class calls into the Handler. | ||
| 767 | |||
| 768 | public void mouseClicked(MouseEvent e) { | ||
| 769 | getHandler().mouseClicked(e); | ||
| 770 | } | ||
| 771 | public void mousePressed(MouseEvent e) { | ||
| 772 | getHandler().mousePressed(e); | ||
| 773 | } | ||
| 774 | public void mouseReleased(MouseEvent e) { | ||
| 775 | getHandler().mouseReleased(e); | ||
| 776 | } | ||
| 777 | public void mouseEntered(MouseEvent e) { | ||
| 778 | getHandler().mouseEntered(e); | ||
| 779 | } | ||
| 780 | public void mouseExited(MouseEvent e) { | ||
| 781 | getHandler().mouseExited(e); | ||
| 782 | } | ||
| 783 | public void mouseDragged(MouseEvent e) { | ||
| 784 | getHandler().mouseDragged(e); | ||
| 785 | } | ||
| 786 | public void mouseMoved(MouseEvent e) { | ||
| 787 | getHandler().mouseMoved(e); | ||
| 788 | } | ||
| 789 | } | ||
| 790 | |||
| 791 | |||
| 792 | private static class Actions extends UIAction { | ||
| 793 | private static final String CLICK = "doClick"; | ||
| 794 | |||
| 795 | Actions(String key) { | ||
| 796 | super(key); | ||
| 797 | } | ||
| 798 | |||
| 799 | public void actionPerformed(ActionEvent e) { | ||
| 800 | JMenuItem mi = (JMenuItem)e.getSource(); | ||
| 801 | MenuSelectionManager.defaultManager().clearSelectedPath(); | ||
| 802 | mi.doClick(); | ||
| 803 | } | ||
| 804 | } | ||
| 805 | |||
| 806 | /** | ||
| 807 | * Call this method when a menu item is to be activated. | ||
| 808 | * This method handles some of the details of menu item activation | ||
| 809 | * such as clearing the selected path and messaging the | ||
| 810 | * JMenuItem's doClick() method. | ||
| 811 | * | ||
| 812 | * @param msm A MenuSelectionManager. The visual feedback and | ||
| 813 | * internal bookkeeping tasks are delegated to | ||
| 814 | * this MenuSelectionManager. If <code>null</code> is | ||
| 815 | * passed as this argument, the | ||
| 816 | * <code>MenuSelectionManager.defaultManager</code> is | ||
| 817 | * used. | ||
| 818 | * @see MenuSelectionManager | ||
| 819 | * @see JMenuItem#doClick(int) | ||
| 820 | * @since 1.4 | ||
| 821 | */ | ||
| 822 | protected void doClick(MenuSelectionManager msm) { | ||
| 823 | // Auditory cue | ||
| 824 | if (! isInternalFrameSystemMenu()) { | ||
| 825 | BasicLookAndFeel.playSound(menuItem, getPropertyPrefix() + | ||
| 826 | ".commandSound"); | ||
| 827 | } | ||
| 828 | // Visual feedback | ||
| 829 | if (msm == null) { | ||
| 830 | msm = MenuSelectionManager.defaultManager(); | ||
| 831 | } | ||
| 832 | msm.clearSelectedPath(); | ||
| 833 | menuItem.doClick(0); | ||
| 834 | } | ||
| 835 | |||
| 836 | /** | ||
| 837 | * This is to see if the menu item in question is part of the | ||
| 838 | * system menu on an internal frame. | ||
| 839 | * The Strings that are being checked can be found in | ||
| 840 | * MetalInternalFrameTitlePaneUI.java, | ||
| 841 | * WindowsInternalFrameTitlePaneUI.java, and | ||
| 842 | * MotifInternalFrameTitlePaneUI.java. | ||
| 843 | * | ||
| 844 | * @since 1.4 | ||
| 845 | */ | ||
| 846 | private boolean isInternalFrameSystemMenu() { | ||
| 847 | String actionCommand = menuItem.getActionCommand(); | ||
| 848 | if ((actionCommand == "Close") || | ||
| 849 | (actionCommand == "Minimize") || | ||
| 850 | (actionCommand == "Restore") || | ||
| 851 | (actionCommand == "Maximize")) { | ||
| 852 | return true; | ||
| 853 | } else { | ||
| 854 | return false; | ||
| 855 | } | ||
| 856 | } | ||
| 857 | |||
| 858 | |||
| 859 | // BasicMenuUI subclasses this. | ||
| 860 | class Handler implements MenuDragMouseListener, | ||
| 861 | MouseInputListener, PropertyChangeListener { | ||
| 862 | // | ||
| 863 | // MouseInputListener | ||
| 864 | // | ||
| 865 | public void mouseClicked(MouseEvent e) {} | ||
| 866 | public void mousePressed(MouseEvent e) { | ||
| 867 | } | ||
| 868 | public void mouseReleased(MouseEvent e) { | ||
| 869 | if (!menuItem.isEnabled()) { | ||
| 870 | return; | ||
| 871 | } | ||
| 872 | MenuSelectionManager manager = | ||
| 873 | MenuSelectionManager.defaultManager(); | ||
| 874 | Point p = e.getPoint(); | ||
| 875 | if(p.x >= 0 && p.x < menuItem.getWidth() && | ||
| 876 | p.y >= 0 && p.y < menuItem.getHeight()) { | ||
| 877 | doClick(manager); | ||
| 878 | } else { | ||
| 879 | manager.processMouseEvent(e); | ||
| 880 | } | ||
| 881 | } | ||
| 882 | public void mouseEntered(MouseEvent e) { | ||
| 883 | MenuSelectionManager manager = MenuSelectionManager.defaultManager(); | ||
| 884 | int modifiers = e.getModifiers(); | ||
| 885 | // 4188027: drag enter/exit added in JDK 1.1.7A, JDK1.2 | ||
| 886 | if ((modifiers & (InputEvent.BUTTON1_MASK | | ||
| 887 | InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK)) !=0 ) { | ||
| 888 | MenuSelectionManager.defaultManager().processMouseEvent(e); | ||
| 889 | } else { | ||
| 890 | manager.setSelectedPath(getPath()); | ||
| 891 | } | ||
| 892 | } | ||
| 893 | public void mouseExited(MouseEvent e) { | ||
| 894 | MenuSelectionManager manager = MenuSelectionManager.defaultManager(); | ||
| 895 | |||
| 896 | int modifiers = e.getModifiers(); | ||
| 897 | // 4188027: drag enter/exit added in JDK 1.1.7A, JDK1.2 | ||
| 898 | if ((modifiers & (InputEvent.BUTTON1_MASK | | ||
| 899 | InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK)) !=0 ) { | ||
| 900 | MenuSelectionManager.defaultManager().processMouseEvent(e); | ||
| 901 | } else { | ||
| 902 | |||
| 903 | MenuElement path[] = manager.getSelectedPath(); | ||
| 904 | if (path.length > 1 && path[path.length-1] == menuItem) { | ||
| 905 | MenuElement newPath[] = new MenuElement[path.length-1]; | ||
| 906 | int i,c; | ||
| 907 | for(i=0,c=path.length-1;i<c;i++) | ||
| 908 | newPath[i] = path[i]; | ||
| 909 | manager.setSelectedPath(newPath); | ||
| 910 | } | ||
| 911 | } | ||
| 912 | } | ||
| 913 | |||
| 914 | public void mouseDragged(MouseEvent e) { | ||
| 915 | MenuSelectionManager.defaultManager().processMouseEvent(e); | ||
| 916 | } | ||
| 917 | public void mouseMoved(MouseEvent e) { | ||
| 918 | } | ||
| 919 | |||
| 920 | // | ||
| 921 | // MenuDragListener | ||
| 922 | // | ||
| 923 | public void menuDragMouseEntered(MenuDragMouseEvent e) { | ||
| 924 | MenuSelectionManager manager = e.getMenuSelectionManager(); | ||
| 925 | MenuElement path[] = e.getPath(); | ||
| 926 | manager.setSelectedPath(path); | ||
| 927 | } | ||
| 928 | public void menuDragMouseDragged(MenuDragMouseEvent e) { | ||
| 929 | MenuSelectionManager manager = e.getMenuSelectionManager(); | ||
| 930 | MenuElement path[] = e.getPath(); | ||
| 931 | manager.setSelectedPath(path); | ||
| 932 | } | ||
| 933 | public void menuDragMouseExited(MenuDragMouseEvent e) {} | ||
| 934 | public void menuDragMouseReleased(MenuDragMouseEvent e) { | ||
| 935 | if (!menuItem.isEnabled()) { | ||
| 936 | return; | ||
| 937 | } | ||
| 938 | MenuSelectionManager manager = e.getMenuSelectionManager(); | ||
| 939 | MenuElement path[] = e.getPath(); | ||
| 940 | Point p = e.getPoint(); | ||
| 941 | if (p.x >= 0 && p.x < menuItem.getWidth() && | ||
| 942 | p.y >= 0 && p.y < menuItem.getHeight()) { | ||
| 943 | doClick(manager); | ||
| 944 | } else { | ||
| 945 | manager.clearSelectedPath(); | ||
| 946 | } | ||
| 947 | } | ||
| 948 | |||
| 949 | |||
| 950 | // | ||
| 951 | // PropertyChangeListener | ||
| 952 | // | ||
| 953 | public void propertyChange(PropertyChangeEvent e) { | ||
| 954 | String name = e.getPropertyName(); | ||
| 955 | |||
| 956 | if (name == "labelFor" || name == "displayedMnemonic" || | ||
| 957 | name == "accelerator") { | ||
| 958 | updateAcceleratorBinding(); | ||
| 959 | } else if (name == "text" || "font" == name || | ||
| 960 | "foreground" == name) { | ||
| 961 | // remove the old html view client property if one | ||
| 962 | // existed, and install a new one if the text installed | ||
| 963 | // into the JLabel is html source. | ||
| 964 | JMenuItem lbl = ((JMenuItem) e.getSource()); | ||
| 965 | String text = lbl.getText(); | ||
| 966 | BasicHTML.updateRenderer(lbl, text); | ||
| 967 | } else if (name == "iconTextGap") { | ||
| 968 | defaultTextIconGap = ((Number)e.getNewValue()).intValue(); | ||
| 969 | } | ||
| 970 | } | ||
| 971 | } | ||
| 972 | } | ||