1 7 package javax.swing.plaf.synth; 8 9 import javax.swing.plaf.basic.BasicHTML ; 10 import java.awt.*; 11 import java.awt.event.*; 12 import java.beans.PropertyChangeEvent ; 13 import java.beans.PropertyChangeListener ; 14 15 import javax.swing.*; 16 import javax.swing.event.*; 17 import javax.swing.border.*; 18 import javax.swing.plaf.*; 19 import javax.swing.plaf.basic.*; 20 import javax.swing.text.View ; 21 import sun.swing.plaf.synth.*; 22 import com.sun.java.swing.SwingUtilities2; 23 24 25 34 class SynthMenuItemUI extends BasicMenuItemUI implements 35 PropertyChangeListener , SynthUI { 36 private SynthStyle style; 37 private SynthStyle accStyle; 38 39 private String acceleratorDelimiter; 40 41 public static ComponentUI createUI(JComponent c) { 42 return new SynthMenuItemUI (); 43 } 44 45 static Dimension getPreferredMenuItemSize(SynthContext context, 51 SynthContext accContext, boolean useCheckAndArrow, JComponent c, 52 Icon checkIcon, Icon arrowIcon, int defaultTextIconGap, 53 String acceleratorDelimiter) { 54 JMenuItem b = (JMenuItem) c; 55 Icon icon = (Icon) b.getIcon(); 56 String text = b.getText(); 57 KeyStroke accelerator = b.getAccelerator(); 58 String acceleratorText = ""; 59 60 if (accelerator != null) { 61 int modifiers = accelerator.getModifiers(); 62 if (modifiers > 0) { 63 acceleratorText = KeyEvent.getKeyModifiersText(modifiers); 64 acceleratorText += acceleratorDelimiter; 65 } 66 int keyCode = accelerator.getKeyCode(); 67 if (keyCode != 0) { 68 acceleratorText += KeyEvent.getKeyText(keyCode); 69 } else { 70 acceleratorText += accelerator.getKeyChar(); 71 } 72 } 73 74 Font font = context.getStyle().getFont(context); 75 FontMetrics fm = b.getFontMetrics(font); 76 FontMetrics fmAccel = b.getFontMetrics(accContext.getStyle(). 77 getFont(accContext)); 78 79 resetRects(); 80 81 layoutMenuItem( 82 context, fm, accContext, text, fmAccel, acceleratorText, 83 icon, checkIcon, arrowIcon, b.getVerticalAlignment(), 84 b.getHorizontalAlignment(), b.getVerticalTextPosition(), 85 b.getHorizontalTextPosition(), viewRect, iconRect, textRect, 86 acceleratorRect, checkIconRect, arrowIconRect, 87 text == null ? 0 : defaultTextIconGap, defaultTextIconGap, 88 useCheckAndArrow); 89 r.setBounds(textRect); 91 r = SwingUtilities.computeUnion(iconRect.x, 92 iconRect.y, 93 iconRect.width, 94 iconRect.height, 95 r); 96 97 100 Container parent = b.getParent(); 102 103 if (parent instanceof JPopupMenu) { 104 SynthPopupMenuUI popupUI = (SynthPopupMenuUI )SynthLookAndFeel. 105 getUIOfType(((JPopupMenu)parent).getUI(), 106 SynthPopupMenuUI .class); 107 108 if (popupUI != null) { 109 r.width = popupUI.adjustTextWidth(r.width); 110 111 popupUI.adjustAcceleratorWidth(acceleratorRect.width); 112 113 r.width += popupUI.getMaxAcceleratorWidth(); 114 } 115 } 116 else if (parent != null && !(b instanceof JMenu && 117 ((JMenu)b).isTopLevelMenu())) { 118 r.width += acceleratorRect.width; 119 } 120 121 if( useCheckAndArrow ) { 122 r.width += checkIconRect.width; 124 r.width += defaultTextIconGap; 125 126 r.width += defaultTextIconGap; 128 r.width += arrowIconRect.width; 129 } 130 131 r.width += 2*defaultTextIconGap; 132 133 Insets insets = b.getInsets(); 134 if(insets != null) { 135 r.width += insets.left + insets.right; 136 r.height += insets.top + insets.bottom; 137 } 138 139 if(r.width%2 == 0) { 142 r.width++; 143 } 144 145 if(r.height%2 == 0) { 148 r.height++; 149 } 150 return r.getSize(); 151 } 152 153 static void paint(SynthContext context, SynthContext accContext, 154 Graphics g, Icon checkIcon, Icon arrowIcon, 155 boolean useCheckAndArrow, String acceleratorDelimiter, 156 int defaultTextIconGap) { 157 JComponent c = context.getComponent(); 158 JMenuItem b = (JMenuItem)c; 159 ButtonModel model = b.getModel(); 160 Insets i = b.getInsets(); 161 162 resetRects(); 163 164 viewRect.setBounds(0, 0, b.getWidth(), b.getHeight()); 165 166 viewRect.x += i.left; 167 viewRect.y += i.top; 168 viewRect.width -= (i.right + viewRect.x); 169 viewRect.height -= (i.bottom + viewRect.y); 170 171 SynthStyle style = context.getStyle(); 172 Font f = style.getFont(context); 173 g.setFont(f); 174 FontMetrics fm = SwingUtilities2.getFontMetrics(c, g, f); 175 FontMetrics accFM = SwingUtilities2.getFontMetrics(c, g, 176 accContext.getStyle(). 177 getFont(accContext)); 178 179 KeyStroke accelerator = b.getAccelerator(); 181 String acceleratorText = ""; 182 if (accelerator != null) { 183 int modifiers = accelerator.getModifiers(); 184 if (modifiers > 0) { 185 acceleratorText = KeyEvent.getKeyModifiersText(modifiers); 186 acceleratorText += acceleratorDelimiter; 187 } 188 189 int keyCode = accelerator.getKeyCode(); 190 if (keyCode != 0) { 191 acceleratorText += KeyEvent.getKeyText(keyCode); 192 } else { 193 acceleratorText += accelerator.getKeyChar(); 194 } 195 } 196 197 String text = layoutMenuItem(context, fm, accContext, 199 b.getText(), accFM, acceleratorText, b.getIcon(), 200 checkIcon, arrowIcon, 201 b.getVerticalAlignment(), b.getHorizontalAlignment(), 202 b.getVerticalTextPosition(), b.getHorizontalTextPosition(), 203 viewRect, iconRect, textRect, acceleratorRect, 204 checkIconRect, arrowIconRect, 205 b.getText() == null ? 0 : defaultTextIconGap, 206 defaultTextIconGap, useCheckAndArrow 207 ); 208 209 if (checkIcon != null && useCheckAndArrow ) { 211 SynthIcon.paintIcon(checkIcon, context, g, checkIconRect.x, 212 checkIconRect.y, checkIconRect.width, checkIconRect.height); 213 } 214 215 if(b.getIcon() != null) { 217 Icon icon; 218 if(!model.isEnabled()) { 219 icon = (Icon) b.getDisabledIcon(); 220 } else if(model.isPressed() && model.isArmed()) { 221 icon = (Icon) b.getPressedIcon(); 222 if(icon == null) { 223 icon = (Icon) b.getIcon(); 225 } 226 } else { 227 icon = (Icon) b.getIcon(); 228 } 229 230 if (icon!=null) { 231 SynthIcon.paintIcon(icon, context, g, iconRect.x, 232 iconRect.y, iconRect.width, iconRect.height); 233 } 234 } 235 236 if(text != null) { 238 View v = (View ) c.getClientProperty(BasicHTML.propertyKey); 239 if (v != null) { 240 v.paint(g, textRect); 241 } else { 242 g.setColor(style.getColor(context, ColorType.TEXT_FOREGROUND)); 243 g.setFont(style.getFont(context)); 244 style.getGraphicsUtils(context).paintText(context, g, text, 245 textRect.x, textRect.y, b.getDisplayedMnemonicIndex()); 246 } 247 } 248 249 if(acceleratorText != null && !acceleratorText.equals("")) { 251 int accOffset = 0; 253 Container parent = b.getParent(); 254 if (parent != null && parent instanceof JPopupMenu) { 255 SynthPopupMenuUI popupUI = (SynthPopupMenuUI ) 256 ((JPopupMenu)parent).getUI(); 257 if (popupUI != null) { 258 int max = popupUI.getMaxAcceleratorWidth(); 261 if (max > 0) { 262 accOffset = max - acceleratorRect.width; 263 } 264 } 265 } 266 267 SynthStyle accStyle = accContext.getStyle(); 268 269 g.setColor(accStyle.getColor(accContext, 270 ColorType.TEXT_FOREGROUND)); 271 g.setFont(accStyle.getFont(accContext)); 272 accStyle.getGraphicsUtils(accContext).paintText( 273 accContext, g, acceleratorText, acceleratorRect.x - 274 accOffset, acceleratorRect.y, -1); 275 } 276 277 if (arrowIcon != null && useCheckAndArrow) { 279 SynthIcon.paintIcon(arrowIcon, context, g, arrowIconRect.x, 280 arrowIconRect.y, arrowIconRect.width, arrowIconRect.height); 281 } 282 } 283 284 290 291 private static String layoutMenuItem( 292 SynthContext context, 293 FontMetrics fm, 294 SynthContext accContext, 295 String text, 296 FontMetrics fmAccel, 297 String acceleratorText, 298 Icon icon, 299 Icon checkIcon, 300 Icon arrowIcon, 301 int verticalAlignment, 302 int horizontalAlignment, 303 int verticalTextPosition, 304 int horizontalTextPosition, 305 Rectangle viewRect, 306 Rectangle iconRect, 307 Rectangle textRect, 308 Rectangle acceleratorRect, 309 Rectangle checkIconRect, 310 Rectangle arrowIconRect, 311 int textIconGap, 312 int menuItemGap, boolean useCheckAndArrow 313 ) 314 { 315 316 context.getStyle().getGraphicsUtils(context).layoutText( 317 context, fm, text, icon,horizontalAlignment, verticalAlignment, 318 horizontalTextPosition, verticalTextPosition, viewRect, 319 iconRect, textRect, textIconGap); 320 321 325 if( (acceleratorText == null) || acceleratorText.equals("") ) { 326 acceleratorRect.width = acceleratorRect.height = 0; 327 acceleratorText = ""; 328 } 329 else { 330 SynthStyle style = accContext.getStyle(); 331 acceleratorRect.width = style.getGraphicsUtils(accContext). 332 computeStringWidth(accContext, fmAccel.getFont(), fmAccel, 333 acceleratorText); 334 acceleratorRect.height = fmAccel.getHeight(); 335 } 336 337 339 340 if( useCheckAndArrow) { 341 if (checkIcon != null) { 342 checkIconRect.width = SynthIcon.getIconWidth(checkIcon, 343 context); 344 checkIconRect.height = SynthIcon.getIconHeight(checkIcon, 345 context); 346 } 347 else { 348 checkIconRect.width = checkIconRect.height = 0; 349 } 350 351 353 354 if (arrowIcon != null) { 355 arrowIconRect.width = SynthIcon.getIconWidth(arrowIcon, 356 context); 357 arrowIconRect.height = SynthIcon.getIconHeight(arrowIcon, 358 context); 359 } else { 360 arrowIconRect.width = arrowIconRect.height = 0; 361 } 362 } 363 364 Rectangle labelRect = iconRect.union(textRect); 365 if( SynthLookAndFeel.isLeftToRight(context.getComponent()) ) { 366 textRect.x += menuItemGap; 367 iconRect.x += menuItemGap; 368 369 acceleratorRect.x = viewRect.x + viewRect.width - 371 arrowIconRect.width - menuItemGap - acceleratorRect.width; 372 373 if (useCheckAndArrow) { 375 checkIconRect.x = viewRect.x + menuItemGap; 376 textRect.x += menuItemGap + checkIconRect.width; 377 iconRect.x += menuItemGap + checkIconRect.width; 378 arrowIconRect.x = viewRect.x + viewRect.width - menuItemGap 379 - arrowIconRect.width; 380 } 381 } else { 382 textRect.x -= menuItemGap; 383 iconRect.x -= menuItemGap; 384 385 acceleratorRect.x = viewRect.x + arrowIconRect.width + menuItemGap; 387 388 if (useCheckAndArrow) { 390 checkIconRect.x = viewRect.x + viewRect.width - menuItemGap 391 - checkIconRect.width; 392 textRect.x -= menuItemGap + checkIconRect.width; 393 iconRect.x -= menuItemGap + checkIconRect.width; 394 arrowIconRect.x = viewRect.x + menuItemGap; 395 } 396 } 397 398 acceleratorRect.y = labelRect.y + (labelRect.height/2) - (acceleratorRect.height/2); 401 if( useCheckAndArrow ) { 402 arrowIconRect.y = labelRect.y + (labelRect.height/2) - (arrowIconRect.height/2); 403 checkIconRect.y = labelRect.y + (labelRect.height/2) - (checkIconRect.height/2); 404 } 405 406 return text; 407 } 408 409 static Rectangle iconRect = new Rectangle(); 412 static Rectangle textRect = new Rectangle(); 413 static Rectangle acceleratorRect = new Rectangle(); 414 static Rectangle checkIconRect = new Rectangle(); 415 static Rectangle arrowIconRect = new Rectangle(); 416 static Rectangle viewRect = new Rectangle(Short.MAX_VALUE,Short.MAX_VALUE); 417 static Rectangle r = new Rectangle(); 418 419 private static void resetRects() { 420 iconRect.setBounds(0, 0, 0, 0); 421 textRect.setBounds(0, 0, 0, 0); 422 acceleratorRect.setBounds(0, 0, 0, 0); 423 checkIconRect.setBounds(0, 0, 0, 0); 424 arrowIconRect.setBounds(0, 0, 0, 0); 425 viewRect.setBounds(0,0,Short.MAX_VALUE, Short.MAX_VALUE); 426 r.setBounds(0, 0, 0, 0); 427 } 428 429 430 protected void installDefaults() { 431 updateStyle(menuItem); 432 } 433 434 protected void installListeners() { 435 super.installListeners(); 436 menuItem.addPropertyChangeListener(this); 437 } 438 439 private void updateStyle(JMenuItem mi) { 440 SynthContext context = getContext(mi, ENABLED); 441 SynthStyle oldStyle = style; 442 443 style = SynthLookAndFeel.updateStyle(context, this); 444 if (oldStyle != style) { 445 String prefix = getPropertyPrefix(); 446 defaultTextIconGap = style.getInt( 447 context, prefix + ".textIconGap", 4); 448 if (menuItem.getMargin() == null || 449 (menuItem.getMargin() instanceof UIResource)) { 450 Insets insets = (Insets)style.get(context, prefix + ".margin"); 451 452 if (insets == null) { 453 insets = SynthLookAndFeel.EMPTY_UIRESOURCE_INSETS; 455 } 456 menuItem.setMargin(insets); 457 } 458 acceleratorDelimiter = style.getString(context, prefix + 459 ".acceleratorDelimiter", "+"); 460 461 arrowIcon = style.getIcon(context, prefix + ".arrowIcon"); 462 463 checkIcon = style.getIcon(context, prefix + ".checkIcon"); 464 if (oldStyle != null) { 465 uninstallKeyboardActions(); 466 installKeyboardActions(); 467 } 468 } 469 context.dispose(); 470 471 SynthContext accContext = getContext(mi, Region.MENU_ITEM_ACCELERATOR, 472 ENABLED); 473 474 accStyle = SynthLookAndFeel.updateStyle(accContext, this); 475 accContext.dispose(); 476 } 477 478 protected void uninstallDefaults() { 479 SynthContext context = getContext(menuItem, ENABLED); 480 style.uninstallDefaults(context); 481 context.dispose(); 482 style = null; 483 484 SynthContext accContext = getContext(menuItem, 485 Region.MENU_ITEM_ACCELERATOR, ENABLED); 486 accStyle.uninstallDefaults(accContext); 487 accContext.dispose(); 488 accStyle = null; 489 490 super.uninstallDefaults(); 491 } 492 493 protected void uninstallListeners() { 494 super.uninstallListeners(); 495 menuItem.removePropertyChangeListener(this); 496 } 497 498 public SynthContext getContext(JComponent c) { 499 return getContext(c, getComponentState(c)); 500 } 501 502 SynthContext getContext(JComponent c, int state) { 503 return SynthContext.getContext(SynthContext .class, c, 504 SynthLookAndFeel.getRegion(c), style, state); 505 } 506 507 public SynthContext getContext(JComponent c, Region region) { 508 return getContext(c, region, getComponentState(c, region)); 509 } 510 511 private SynthContext getContext(JComponent c, Region region, int state) { 512 return SynthContext.getContext(SynthContext .class, c, 513 region, accStyle, state); 514 } 515 516 private Region getRegion(JComponent c) { 517 return SynthLookAndFeel.getRegion(c); 518 } 519 520 private int getComponentState(JComponent c) { 521 int state; 522 523 if (!c.isEnabled()) { 524 state = DISABLED; 525 } else { 526 if (menuItem.isArmed()) { 527 state = MOUSE_OVER; 528 } 529 else { 530 state = SynthLookAndFeel.getComponentState(c); 531 } 532 } 533 if (menuItem.isSelected()) { 534 state |= SELECTED; 535 } 536 return state; 537 } 538 539 private int getComponentState(JComponent c, Region region) { 540 return getComponentState(c); 541 } 542 543 protected Dimension getPreferredMenuItemSize(JComponent c, 544 Icon checkIcon, 545 Icon arrowIcon, 546 int defaultTextIconGap) { 547 SynthContext context = getContext(c); 548 SynthContext accContext = getContext(c, Region.MENU_ITEM_ACCELERATOR); 549 Dimension value = getPreferredMenuItemSize(context, accContext, 550 true, c, checkIcon, arrowIcon, defaultTextIconGap, 551 acceleratorDelimiter); 552 context.dispose(); 553 accContext.dispose(); 554 return value; 555 } 556 557 558 public void update(Graphics g, JComponent c) { 559 SynthContext context = getContext(c); 560 561 SynthLookAndFeel.update(context, g); 562 paintBackground(context, g, c); 563 paint(context, g); 564 context.dispose(); 565 } 566 567 public void paint(Graphics g, JComponent c) { 568 SynthContext context = getContext(c); 569 570 paint(context, g); 571 context.dispose(); 572 } 573 574 protected void paint(SynthContext context, Graphics g) { 575 SynthContext accContext = getContext(menuItem, 576 Region.MENU_ITEM_ACCELERATOR); 577 578 String prefix = getPropertyPrefix(); 579 paint(context, accContext, g, 580 style.getIcon(getContext(context.getComponent()), 581 prefix + ".checkIcon"), 582 style.getIcon(getContext(context.getComponent()), 583 prefix + ".arrowIcon"), 584 true, acceleratorDelimiter, defaultTextIconGap); 585 accContext.dispose(); 586 } 587 588 void paintBackground(SynthContext context, Graphics g, JComponent c) { 589 context.getPainter().paintMenuItemBackground(context, g, 0, 0, 590 c.getWidth(), c.getHeight()); 591 } 592 593 public void paintBorder(SynthContext context, Graphics g, int x, 594 int y, int w, int h) { 595 context.getPainter().paintMenuItemBorder(context, g, x, y, w, h); 596 } 597 598 public void propertyChange(PropertyChangeEvent e) { 599 if (SynthLookAndFeel.shouldUpdateStyle(e)) { 600 updateStyle((JMenuItem)e.getSource()); 601 } 602 } 603 } 604 | Popular Tags |