1 /* 2 * Copyright (c) 1998, 2014, 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.metal; 27 28 import javax.swing.*; 29 import javax.swing.border.*; 30 import javax.swing.plaf.*; 31 import javax.swing.plaf.basic.BasicBorders; 32 import javax.swing.text.JTextComponent; 33 34 import java.awt.Component; 35 import java.awt.Insets; 36 import java.awt.Color; 37 import java.awt.Dialog; 38 import java.awt.Frame; 39 import java.awt.Graphics; 40 import java.awt.Window; 41 42 import sun.swing.StringUIClientPropertyKey; 43 44 45 /** 46 * Factory object that can vend Borders appropriate for the metal L & F. 47 * @author Steve Wilson 48 */ 49 50 public class MetalBorders { 51 52 /** 53 * Client property indicating the button shouldn't provide a rollover 54 * indicator. Only used with the Ocean theme. 55 */ 56 static Object NO_BUTTON_ROLLOVER = 57 new StringUIClientPropertyKey("NoButtonRollover"); 58 59 @SuppressWarnings("serial") // Superclass is not serializable across versions 60 public static class Flush3DBorder extends AbstractBorder implements UIResource{ 61 public void paintBorder(Component c, Graphics g, int x, int y, 62 int w, int h) { 63 if (c.isEnabled()) { 64 MetalUtils.drawFlush3DBorder(g, x, y, w, h); 65 } else { 66 MetalUtils.drawDisabledBorder(g, x, y, w, h); 67 } 68 } 69 70 public Insets getBorderInsets(Component c, Insets newInsets) { 71 newInsets.set(2, 2, 2, 2); 72 return newInsets; 73 } 74 } 75 76 @SuppressWarnings("serial") // Superclass is not serializable across versions 77 public static class ButtonBorder extends AbstractBorder implements UIResource { 78 79 protected static Insets borderInsets = new Insets( 3, 3, 3, 3 ); 80 81 public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { 82 if (!(c instanceof AbstractButton)) { 83 return; 84 } 85 if (MetalLookAndFeel.usingOcean()) { 86 paintOceanBorder(c, g, x, y, w, h); 87 return; 88 } 89 AbstractButton button = (AbstractButton)c; 90 ButtonModel model = button.getModel(); 91 92 if ( model.isEnabled() ) { 93 boolean isPressed = model.isPressed() && model.isArmed(); 94 boolean isDefault = (button instanceof JButton && ((JButton)button).isDefaultButton()); 95 96 if (isPressed && isDefault) { 97 MetalUtils.drawDefaultButtonPressedBorder(g, x, y, w, h); 98 } else if (isPressed) { 99 MetalUtils.drawPressed3DBorder( g, x, y, w, h ); 100 } else if (isDefault) { 101 MetalUtils.drawDefaultButtonBorder( g, x, y, w, h, false); 102 } else { 103 MetalUtils.drawButtonBorder( g, x, y, w, h, false); 104 } 105 } else { // disabled state 106 MetalUtils.drawDisabledBorder( g, x, y, w-1, h-1 ); 107 } 108 } 109 110 private void paintOceanBorder(Component c, Graphics g, int x, int y, 111 int w, int h) { 112 AbstractButton button = (AbstractButton)c; 113 ButtonModel model = ((AbstractButton)c).getModel(); 114 115 g.translate(x, y); 116 if (MetalUtils.isToolBarButton(button)) { 117 if (model.isEnabled()) { 118 if (model.isPressed()) { 119 g.setColor(MetalLookAndFeel.getWhite()); 120 g.fillRect(1, h - 1, w - 1, 1); 121 g.fillRect(w - 1, 1, 1, h - 1); 122 g.setColor(MetalLookAndFeel.getControlDarkShadow()); 123 g.drawRect(0, 0, w - 2, h - 2); 124 g.fillRect(1, 1, w - 3, 1); 125 } 126 else if (model.isSelected() || model.isRollover()) { 127 g.setColor(MetalLookAndFeel.getWhite()); 128 g.fillRect(1, h - 1, w - 1, 1); 129 g.fillRect(w - 1, 1, 1, h - 1); 130 g.setColor(MetalLookAndFeel.getControlDarkShadow()); 131 g.drawRect(0, 0, w - 2, h - 2); 132 } 133 else { 134 g.setColor(MetalLookAndFeel.getWhite()); 135 g.drawRect(1, 1, w - 2, h - 2); 136 g.setColor(UIManager.getColor( 137 "Button.toolBarBorderBackground")); 138 g.drawRect(0, 0, w - 2, h - 2); 139 } 140 } 141 else { 142 g.setColor(UIManager.getColor( 143 "Button.disabledToolBarBorderBackground")); 144 g.drawRect(0, 0, w - 2, h - 2); 145 } 146 } 147 else if (model.isEnabled()) { 148 boolean pressed = model.isPressed(); 149 boolean armed = model.isArmed(); 150 151 if ((c instanceof JButton) && ((JButton)c).isDefaultButton()) { 152 g.setColor(MetalLookAndFeel.getControlDarkShadow()); 153 g.drawRect(0, 0, w - 1, h - 1); 154 g.drawRect(1, 1, w - 3, h - 3); 155 } 156 else if (pressed) { 157 g.setColor(MetalLookAndFeel.getControlDarkShadow()); 158 g.fillRect(0, 0, w, 2); 159 g.fillRect(0, 2, 2, h - 2); 160 g.fillRect(w - 1, 1, 1, h - 1); 161 g.fillRect(1, h - 1, w - 2, 1); 162 } 163 else if (model.isRollover() && button.getClientProperty( 164 NO_BUTTON_ROLLOVER) == null) { 165 g.setColor(MetalLookAndFeel.getPrimaryControl()); 166 g.drawRect(0, 0, w - 1, h - 1); 167 g.drawRect(2, 2, w - 5, h - 5); 168 g.setColor(MetalLookAndFeel.getControlDarkShadow()); 169 g.drawRect(1, 1, w - 3, h - 3); 170 } 171 else { 172 g.setColor(MetalLookAndFeel.getControlDarkShadow()); 173 g.drawRect(0, 0, w - 1, h - 1); 174 } 175 } 176 else { 177 g.setColor(MetalLookAndFeel.getInactiveControlTextColor()); 178 g.drawRect(0, 0, w - 1, h - 1); 179 if ((c instanceof JButton) && ((JButton)c).isDefaultButton()) { 180 g.drawRect(1, 1, w - 3, h - 3); 181 } 182 } 183 } 184 185 public Insets getBorderInsets(Component c, Insets newInsets) { 186 newInsets.set(3, 3, 3, 3); 187 return newInsets; 188 } 189 } 190 191 @SuppressWarnings("serial") // Superclass is not serializable across versions 192 public static class InternalFrameBorder extends AbstractBorder implements UIResource { 193 private static final int corner = 14; 194 195 public void paintBorder(Component c, Graphics g, int x, int y, 196 int w, int h) { 197 198 Color background; 199 Color highlight; 200 Color shadow; 201 202 if (c instanceof JInternalFrame && ((JInternalFrame)c).isSelected()) { 203 background = MetalLookAndFeel.getPrimaryControlDarkShadow(); 204 highlight = MetalLookAndFeel.getPrimaryControlShadow(); 205 shadow = MetalLookAndFeel.getPrimaryControlInfo(); 206 } else { 207 background = MetalLookAndFeel.getControlDarkShadow(); 208 highlight = MetalLookAndFeel.getControlShadow(); 209 shadow = MetalLookAndFeel.getControlInfo(); 210 } 211 212 g.setColor(background); 213 // Draw outermost lines 214 g.drawLine( 1, 0, w-2, 0); 215 g.drawLine( 0, 1, 0, h-2); 216 g.drawLine( w-1, 1, w-1, h-2); 217 g.drawLine( 1, h-1, w-2, h-1); 218 219 // Draw the bulk of the border 220 for (int i = 1; i < 5; i++) { 221 g.drawRect(x+i,y+i,w-(i*2)-1, h-(i*2)-1); 222 } 223 224 if (c instanceof JInternalFrame && 225 ((JInternalFrame)c).isResizable()) { 226 g.setColor(highlight); 227 // Draw the Long highlight lines 228 g.drawLine( corner+1, 3, w-corner, 3); 229 g.drawLine( 3, corner+1, 3, h-corner); 230 g.drawLine( w-2, corner+1, w-2, h-corner); 231 g.drawLine( corner+1, h-2, w-corner, h-2); 232 233 g.setColor(shadow); 234 // Draw the Long shadow lines 235 g.drawLine( corner, 2, w-corner-1, 2); 236 g.drawLine( 2, corner, 2, h-corner-1); 237 g.drawLine( w-3, corner, w-3, h-corner-1); 238 g.drawLine( corner, h-3, w-corner-1, h-3); 239 } 240 241 } 242 243 public Insets getBorderInsets(Component c, Insets newInsets) { 244 newInsets.set(5, 5, 5, 5); 245 return newInsets; 246 } 247 } 248 249 /** 250 * Border for a Frame. 251 * @since 1.4 252 */ 253 @SuppressWarnings("serial") // Superclass is not serializable across versions 254 static class FrameBorder extends AbstractBorder implements UIResource { 255 private static final int corner = 14; 256 257 public void paintBorder(Component c, Graphics g, int x, int y, 258 int w, int h) { 259 260 Color background; 261 Color highlight; 262 Color shadow; 263 264 Window window = SwingUtilities.getWindowAncestor(c); 265 if (window != null && window.isActive()) { 266 background = MetalLookAndFeel.getPrimaryControlDarkShadow(); 267 highlight = MetalLookAndFeel.getPrimaryControlShadow(); 268 shadow = MetalLookAndFeel.getPrimaryControlInfo(); 269 } else { 270 background = MetalLookAndFeel.getControlDarkShadow(); 271 highlight = MetalLookAndFeel.getControlShadow(); 272 shadow = MetalLookAndFeel.getControlInfo(); 273 } 274 275 g.setColor(background); 276 // Draw outermost lines 277 g.drawLine( x+1, y+0, x+w-2, y+0); 278 g.drawLine( x+0, y+1, x+0, y +h-2); 279 g.drawLine( x+w-1, y+1, x+w-1, y+h-2); 280 g.drawLine( x+1, y+h-1, x+w-2, y+h-1); 281 282 // Draw the bulk of the border 283 for (int i = 1; i < 5; i++) { 284 g.drawRect(x+i,y+i,w-(i*2)-1, h-(i*2)-1); 285 } 286 287 if ((window instanceof Frame) && ((Frame) window).isResizable()) { 288 g.setColor(highlight); 289 // Draw the Long highlight lines 290 g.drawLine( corner+1, 3, w-corner, 3); 291 g.drawLine( 3, corner+1, 3, h-corner); 292 g.drawLine( w-2, corner+1, w-2, h-corner); 293 g.drawLine( corner+1, h-2, w-corner, h-2); 294 295 g.setColor(shadow); 296 // Draw the Long shadow lines 297 g.drawLine( corner, 2, w-corner-1, 2); 298 g.drawLine( 2, corner, 2, h-corner-1); 299 g.drawLine( w-3, corner, w-3, h-corner-1); 300 g.drawLine( corner, h-3, w-corner-1, h-3); 301 } 302 303 } 304 305 public Insets getBorderInsets(Component c, Insets newInsets) 306 { 307 newInsets.set(5, 5, 5, 5); 308 return newInsets; 309 } 310 } 311 312 /** 313 * Border for a Frame. 314 * @since 1.4 315 */ 316 @SuppressWarnings("serial") // Superclass is not serializable across versions 317 static class DialogBorder extends AbstractBorder implements UIResource 318 { 319 private static final int corner = 14; 320 321 protected Color getActiveBackground() 322 { 323 return MetalLookAndFeel.getPrimaryControlDarkShadow(); 324 } 325 326 protected Color getActiveHighlight() 327 { 328 return MetalLookAndFeel.getPrimaryControlShadow(); 329 } 330 331 protected Color getActiveShadow() 332 { 333 return MetalLookAndFeel.getPrimaryControlInfo(); 334 } 335 336 protected Color getInactiveBackground() 337 { 338 return MetalLookAndFeel.getControlDarkShadow(); 339 } 340 341 protected Color getInactiveHighlight() 342 { 343 return MetalLookAndFeel.getControlShadow(); 344 } 345 346 protected Color getInactiveShadow() 347 { 348 return MetalLookAndFeel.getControlInfo(); 349 } 350 351 public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) 352 { 353 Color background; 354 Color highlight; 355 Color shadow; 356 357 Window window = SwingUtilities.getWindowAncestor(c); 358 if (window != null && window.isActive()) { 359 background = getActiveBackground(); 360 highlight = getActiveHighlight(); 361 shadow = getActiveShadow(); 362 } else { 363 background = getInactiveBackground(); 364 highlight = getInactiveHighlight(); 365 shadow = getInactiveShadow(); 366 } 367 368 g.setColor(background); 369 // Draw outermost lines 370 g.drawLine( x + 1, y + 0, x + w-2, y + 0); 371 g.drawLine( x + 0, y + 1, x + 0, y + h - 2); 372 g.drawLine( x + w - 1, y + 1, x + w - 1, y + h - 2); 373 g.drawLine( x + 1, y + h - 1, x + w - 2, y + h - 1); 374 375 // Draw the bulk of the border 376 for (int i = 1; i < 5; i++) { 377 g.drawRect(x+i,y+i,w-(i*2)-1, h-(i*2)-1); 378 } 379 380 381 if ((window instanceof Dialog) && ((Dialog) window).isResizable()) { 382 g.setColor(highlight); 383 // Draw the Long highlight lines 384 g.drawLine( corner+1, 3, w-corner, 3); 385 g.drawLine( 3, corner+1, 3, h-corner); 386 g.drawLine( w-2, corner+1, w-2, h-corner); 387 g.drawLine( corner+1, h-2, w-corner, h-2); 388 389 g.setColor(shadow); 390 // Draw the Long shadow lines 391 g.drawLine( corner, 2, w-corner-1, 2); 392 g.drawLine( 2, corner, 2, h-corner-1); 393 g.drawLine( w-3, corner, w-3, h-corner-1); 394 g.drawLine( corner, h-3, w-corner-1, h-3); 395 } 396 397 } 398 399 public Insets getBorderInsets(Component c, Insets newInsets) 400 { 401 newInsets.set(5, 5, 5, 5); 402 return newInsets; 403 } 404 } 405 406 /** 407 * Border for an Error Dialog. 408 * @since 1.4 409 */ 410 @SuppressWarnings("serial") // Superclass is not serializable across versions 411 static class ErrorDialogBorder extends DialogBorder implements UIResource 412 { 413 protected Color getActiveBackground() { 414 return UIManager.getColor("OptionPane.errorDialog.border.background"); 415 } 416 } 417 418 419 /** 420 * Border for a QuestionDialog. Also used for a JFileChooser and a 421 * JColorChooser.. 422 * @since 1.4 423 */ 424 @SuppressWarnings("serial") // Superclass is not serializable across versions 425 static class QuestionDialogBorder extends DialogBorder implements UIResource 426 { 427 protected Color getActiveBackground() { 428 return UIManager.getColor("OptionPane.questionDialog.border.background"); 429 } 430 } 431 432 433 /** 434 * Border for a Warning Dialog. 435 * @since 1.4 436 */ 437 @SuppressWarnings("serial") // Superclass is not serializable across versions 438 static class WarningDialogBorder extends DialogBorder implements UIResource 439 { 440 protected Color getActiveBackground() { 441 return UIManager.getColor("OptionPane.warningDialog.border.background"); 442 } 443 } 444 445 446 /** 447 * Border for a Palette. 448 * @since 1.3 449 */ 450 @SuppressWarnings("serial") // Superclass is not serializable across versions 451 public static class PaletteBorder extends AbstractBorder implements UIResource { 452 int titleHeight = 0; 453 454 public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) { 455 456 g.translate(x,y); 457 g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow()); 458 g.drawLine(0, 1, 0, h-2); 459 g.drawLine(1, h-1, w-2, h-1); 460 g.drawLine(w-1, 1, w-1, h-2); 461 g.drawLine( 1, 0, w-2, 0); 462 g.drawRect(1,1, w-3, h-3); 463 g.translate(-x,-y); 464 465 } 466 467 public Insets getBorderInsets(Component c, Insets newInsets) { 468 newInsets.set(1, 1, 1, 1); 469 return newInsets; 470 } 471 } 472 473 @SuppressWarnings("serial") // Superclass is not serializable across versions 474 public static class OptionDialogBorder extends AbstractBorder implements UIResource { 475 int titleHeight = 0; 476 477 public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) { 478 479 g.translate(x,y); 480 481 int messageType = JOptionPane.PLAIN_MESSAGE; 482 if (c instanceof JInternalFrame) { 483 Object obj = ((JInternalFrame) c).getClientProperty( 484 "JInternalFrame.messageType"); 485 if (obj instanceof Integer) { 486 messageType = (Integer) obj; 487 } 488 } 489 490 Color borderColor; 491 492 switch (messageType) { 493 case(JOptionPane.ERROR_MESSAGE): 494 borderColor = UIManager.getColor( 495 "OptionPane.errorDialog.border.background"); 496 break; 497 case(JOptionPane.QUESTION_MESSAGE): 498 borderColor = UIManager.getColor( 499 "OptionPane.questionDialog.border.background"); 500 break; 501 case(JOptionPane.WARNING_MESSAGE): 502 borderColor = UIManager.getColor( 503 "OptionPane.warningDialog.border.background"); 504 break; 505 case(JOptionPane.INFORMATION_MESSAGE): 506 case(JOptionPane.PLAIN_MESSAGE): 507 default: 508 borderColor = MetalLookAndFeel.getPrimaryControlDarkShadow(); 509 break; 510 } 511 512 g.setColor(borderColor); 513 514 // Draw outermost lines 515 g.drawLine( 1, 0, w-2, 0); 516 g.drawLine( 0, 1, 0, h-2); 517 g.drawLine( w-1, 1, w-1, h-2); 518 g.drawLine( 1, h-1, w-2, h-1); 519 520 // Draw the bulk of the border 521 for (int i = 1; i < 3; i++) { 522 g.drawRect(i, i, w-(i*2)-1, h-(i*2)-1); 523 } 524 525 g.translate(-x,-y); 526 527 } 528 529 public Insets getBorderInsets(Component c, Insets newInsets) { 530 newInsets.set(3, 3, 3, 3); 531 return newInsets; 532 } 533 } 534 535 @SuppressWarnings("serial") // Superclass is not serializable across versions 536 public static class MenuBarBorder extends AbstractBorder implements UIResource { 537 protected static Insets borderInsets = new Insets( 1, 0, 1, 0 ); 538 539 public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) { 540 g.translate( x, y ); 541 542 if (MetalLookAndFeel.usingOcean()) { 543 // Only paint a border if we're not next to a horizontal 544 // toolbar 545 if ((c instanceof JMenuBar) && !MetalToolBarUI.doesMenuBarBorderToolBar((JMenuBar)c)) { 546 g.setColor(MetalLookAndFeel.getControl()); 547 g.drawLine(0, h - 2, w, h - 2); 548 g.setColor(UIManager.getColor("MenuBar.borderColor")); 549 g.drawLine(0, h - 1, w, h - 1); 550 } 551 } 552 else { 553 g.setColor( MetalLookAndFeel.getControlShadow() ); 554 g.drawLine( 0, h-1, w, h-1 ); 555 } 556 557 g.translate( -x, -y ); 558 559 } 560 561 public Insets getBorderInsets(Component c, Insets newInsets) { 562 if (MetalLookAndFeel.usingOcean()) { 563 newInsets.set(0, 0, 2, 0); 564 } 565 else { 566 newInsets.set(1, 0, 1, 0); 567 } 568 return newInsets; 569 } 570 } 571 572 @SuppressWarnings("serial") // Superclass is not serializable across versions 573 public static class MenuItemBorder extends AbstractBorder implements UIResource { 574 protected static Insets borderInsets = new Insets( 2, 2, 2, 2 ); 575 576 public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) { 577 if (!(c instanceof JMenuItem)) { 578 return; 579 } 580 JMenuItem b = (JMenuItem) c; 581 ButtonModel model = b.getModel(); 582 583 g.translate( x, y ); 584 585 if ( c.getParent() instanceof JMenuBar ) { 586 if ( model.isArmed() || model.isSelected() ) { 587 g.setColor( MetalLookAndFeel.getControlDarkShadow() ); 588 g.drawLine( 0, 0, w - 2, 0 ); 589 g.drawLine( 0, 0, 0, h - 1 ); 590 g.drawLine( w - 2, 2, w - 2, h - 1 ); 591 592 g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() ); 593 g.drawLine( w - 1, 1, w - 1, h - 1 ); 594 595 g.setColor( MetalLookAndFeel.getMenuBackground() ); 596 g.drawLine( w - 1, 0, w - 1, 0 ); 597 } 598 } else { 599 if ( model.isArmed() || ( c instanceof JMenu && model.isSelected() ) ) { 600 g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() ); 601 g.drawLine( 0, 0, w - 1, 0 ); 602 603 g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() ); 604 g.drawLine( 0, h - 1, w - 1, h - 1 ); 605 } else { 606 g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() ); 607 g.drawLine( 0, 0, 0, h - 1 ); 608 } 609 } 610 611 g.translate( -x, -y ); 612 } 613 614 public Insets getBorderInsets(Component c, Insets newInsets) { 615 newInsets.set(2, 2, 2, 2); 616 return newInsets; 617 } 618 } 619 620 @SuppressWarnings("serial") // Superclass is not serializable across versions 621 public static class PopupMenuBorder extends AbstractBorder implements UIResource { 622 protected static Insets borderInsets = new Insets( 3, 1, 2, 1 ); 623 624 public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) { 625 g.translate( x, y ); 626 627 g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() ); 628 g.drawRect( 0, 0, w - 1, h - 1 ); 629 630 g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() ); 631 g.drawLine( 1, 1, w - 2, 1 ); 632 g.drawLine( 1, 2, 1, 2 ); 633 g.drawLine( 1, h - 2, 1, h - 2 ); 634 635 g.translate( -x, -y ); 636 637 } 638 639 public Insets getBorderInsets(Component c, Insets newInsets) { 640 newInsets.set(3, 1, 2, 1); 641 return newInsets; 642 } 643 } 644 645 @SuppressWarnings("serial") // Superclass is not serializable across versions 646 public static class RolloverButtonBorder extends ButtonBorder { 647 648 public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) { 649 AbstractButton b = (AbstractButton) c; 650 ButtonModel model = b.getModel(); 651 652 if ( model.isRollover() && !( model.isPressed() && !model.isArmed() ) ) { 653 super.paintBorder( c, g, x, y, w, h ); 654 } 655 } 656 657 } 658 659 /** 660 * A border which is like a Margin border but it will only honor the margin 661 * if the margin has been explicitly set by the developer. 662 * 663 * Note: This is identical to the package private class 664 * BasicBorders.RolloverMarginBorder and should probably be consolidated. 665 */ 666 @SuppressWarnings("serial") // Superclass is not serializable across versions 667 static class RolloverMarginBorder extends EmptyBorder { 668 669 public RolloverMarginBorder() { 670 super(3,3,3,3); // hardcoded margin for JLF requirements. 671 } 672 673 public Insets getBorderInsets(Component c, Insets insets) { 674 Insets margin = null; 675 676 if (c instanceof AbstractButton) { 677 margin = ((AbstractButton)c).getMargin(); 678 } 679 if (margin == null || margin instanceof UIResource) { 680 // default margin so replace 681 insets.left = left; 682 insets.top = top; 683 insets.right = right; 684 insets.bottom = bottom; 685 } else { 686 // Margin which has been explicitly set by the user. 687 insets.left = margin.left; 688 insets.top = margin.top; 689 insets.right = margin.right; 690 insets.bottom = margin.bottom; 691 } 692 return insets; 693 } 694 } 695 696 @SuppressWarnings("serial") // Superclass is not serializable across versions 697 public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants 698 { 699 protected MetalBumps bumps = new MetalBumps( 10, 10, 700 MetalLookAndFeel.getControlHighlight(), 701 MetalLookAndFeel.getControlDarkShadow(), 702 UIManager.getColor("ToolBar.background")); 703 704 public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) 705 { 706 if (!(c instanceof JToolBar)) { 707 return; 708 } 709 g.translate( x, y ); 710 711 if ( ((JToolBar) c).isFloatable() ) 712 { 713 if ( ((JToolBar) c).getOrientation() == HORIZONTAL ) 714 { 715 int shift = MetalLookAndFeel.usingOcean() ? -1 : 0; 716 bumps.setBumpArea( 10, h - 4 ); 717 if( MetalUtils.isLeftToRight(c) ) { 718 bumps.paintIcon( c, g, 2, 2 + shift ); 719 } else { 720 bumps.paintIcon( c, g, w-12, 721 2 + shift ); 722 } 723 } 724 else // vertical 725 { 726 bumps.setBumpArea( w - 4, 10 ); 727 bumps.paintIcon( c, g, 2, 2 ); 728 } 729 730 } 731 732 if (((JToolBar) c).getOrientation() == HORIZONTAL && 733 MetalLookAndFeel.usingOcean()) { 734 g.setColor(MetalLookAndFeel.getControl()); 735 g.drawLine(0, h - 2, w, h - 2); 736 g.setColor(UIManager.getColor("ToolBar.borderColor")); 737 g.drawLine(0, h - 1, w, h - 1); 738 } 739 740 g.translate( -x, -y ); 741 } 742 743 public Insets getBorderInsets(Component c, Insets newInsets) { 744 if (MetalLookAndFeel.usingOcean()) { 745 newInsets.set(1, 2, 3, 2); 746 } 747 else { 748 newInsets.top = newInsets.left = newInsets.bottom = newInsets.right = 2; 749 } 750 751 if (!(c instanceof JToolBar)) { 752 return newInsets; 753 } 754 if ( ((JToolBar) c).isFloatable() ) { 755 if ( ((JToolBar) c).getOrientation() == HORIZONTAL ) { 756 if (c.getComponentOrientation().isLeftToRight()) { 757 newInsets.left = 16; 758 } else { 759 newInsets.right = 16; 760 } 761 } else {// vertical 762 newInsets.top = 16; 763 } 764 } 765 766 Insets margin = ((JToolBar) c).getMargin(); 767 768 if ( margin != null ) { 769 newInsets.left += margin.left; 770 newInsets.top += margin.top; 771 newInsets.right += margin.right; 772 newInsets.bottom += margin.bottom; 773 } 774 775 return newInsets; 776 } 777 } 778 779 private static Border buttonBorder; 780 781 /** 782 * Returns a border instance for a JButton 783 * @since 1.3 784 */ 785 public static Border getButtonBorder() { 786 if (buttonBorder == null) { 787 buttonBorder = new BorderUIResource.CompoundBorderUIResource( 788 new MetalBorders.ButtonBorder(), 789 new BasicBorders.MarginBorder()); 790 } 791 return buttonBorder; 792 } 793 794 private static Border textBorder; 795 796 /** 797 * Returns a border instance for a text component 798 * @since 1.3 799 */ 800 public static Border getTextBorder() { 801 if (textBorder == null) { 802 textBorder = new BorderUIResource.CompoundBorderUIResource( 803 new MetalBorders.Flush3DBorder(), 804 new BasicBorders.MarginBorder()); 805 } 806 return textBorder; 807 } 808 809 private static Border textFieldBorder; 810 811 /** 812 * Returns a border instance for a JTextField 813 * @since 1.3 814 */ 815 public static Border getTextFieldBorder() { 816 if (textFieldBorder == null) { 817 textFieldBorder = new BorderUIResource.CompoundBorderUIResource( 818 new MetalBorders.TextFieldBorder(), 819 new BasicBorders.MarginBorder()); 820 } 821 return textFieldBorder; 822 } 823 824 @SuppressWarnings("serial") // Superclass is not serializable across versions 825 public static class TextFieldBorder extends Flush3DBorder { 826 827 public void paintBorder(Component c, Graphics g, int x, int y, 828 int w, int h) { 829 830 if (!(c instanceof JTextComponent)) { 831 // special case for non-text components (bug ID 4144840) 832 if (c.isEnabled()) { 833 MetalUtils.drawFlush3DBorder(g, x, y, w, h); 834 } else { 835 MetalUtils.drawDisabledBorder(g, x, y, w, h); 836 } 837 return; 838 } 839 840 if (c.isEnabled() && ((JTextComponent)c).isEditable()) { 841 MetalUtils.drawFlush3DBorder(g, x, y, w, h); 842 } else { 843 MetalUtils.drawDisabledBorder(g, x, y, w, h); 844 } 845 846 } 847 } 848 849 @SuppressWarnings("serial") // Superclass is not serializable across versions 850 public static class ScrollPaneBorder extends AbstractBorder implements UIResource { 851 public void paintBorder(Component c, Graphics g, int x, int y, 852 int w, int h) { 853 854 if (!(c instanceof JScrollPane)) { 855 return; 856 } 857 JScrollPane scroll = (JScrollPane)c; 858 JComponent colHeader = scroll.getColumnHeader(); 859 int colHeaderHeight = 0; 860 if (colHeader != null) 861 colHeaderHeight = colHeader.getHeight(); 862 863 JComponent rowHeader = scroll.getRowHeader(); 864 int rowHeaderWidth = 0; 865 if (rowHeader != null) 866 rowHeaderWidth = rowHeader.getWidth(); 867 868 869 g.translate( x, y); 870 871 g.setColor( MetalLookAndFeel.getControlDarkShadow() ); 872 g.drawRect( 0, 0, w-2, h-2 ); 873 g.setColor( MetalLookAndFeel.getControlHighlight() ); 874 875 g.drawLine( w-1, 1, w-1, h-1); 876 g.drawLine( 1, h-1, w-1, h-1); 877 878 g.setColor( MetalLookAndFeel.getControl() ); 879 g.drawLine( w-2, 2+colHeaderHeight, w-2, 2+colHeaderHeight ); 880 g.drawLine( 1+rowHeaderWidth, h-2, 1+rowHeaderWidth, h-2 ); 881 882 g.translate( -x, -y); 883 884 } 885 886 public Insets getBorderInsets(Component c, Insets insets) { 887 insets.set(1, 1, 2, 2); 888 return insets; 889 } 890 } 891 892 private static Border toggleButtonBorder; 893 894 /** 895 * Returns a border instance for a JToggleButton 896 * @since 1.3 897 */ 898 public static Border getToggleButtonBorder() { 899 if (toggleButtonBorder == null) { 900 toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource( 901 new MetalBorders.ToggleButtonBorder(), 902 new BasicBorders.MarginBorder()); 903 } 904 return toggleButtonBorder; 905 } 906 907 /** 908 * @since 1.3 909 */ 910 @SuppressWarnings("serial") // Superclass is not serializable across versions 911 public static class ToggleButtonBorder extends ButtonBorder { 912 public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { 913 AbstractButton button = (AbstractButton)c; 914 ButtonModel model = button.getModel(); 915 if (MetalLookAndFeel.usingOcean()) { 916 if(model.isArmed() || !button.isEnabled()) { 917 super.paintBorder(c, g, x, y, w, h); 918 } 919 else { 920 g.setColor(MetalLookAndFeel.getControlDarkShadow()); 921 g.drawRect(0, 0, w - 1, h - 1); 922 } 923 return; 924 } 925 if (! c.isEnabled() ) { 926 MetalUtils.drawDisabledBorder( g, x, y, w-1, h-1 ); 927 } else { 928 if ( model.isPressed() && model.isArmed() ) { 929 MetalUtils.drawPressed3DBorder( g, x, y, w, h ); 930 } else if ( model.isSelected() ) { 931 MetalUtils.drawDark3DBorder( g, x, y, w, h ); 932 } else { 933 MetalUtils.drawFlush3DBorder( g, x, y, w, h ); 934 } 935 } 936 } 937 } 938 939 /** 940 * Border for a Table Header 941 * @since 1.3 942 */ 943 @SuppressWarnings("serial") // Superclass is not serializable across versions 944 public static class TableHeaderBorder extends javax.swing.border.AbstractBorder { 945 protected Insets editorBorderInsets = new Insets( 2, 2, 2, 0 ); 946 947 public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { 948 g.translate( x, y ); 949 950 g.setColor( MetalLookAndFeel.getControlDarkShadow() ); 951 g.drawLine( w-1, 0, w-1, h-1 ); 952 g.drawLine( 1, h-1, w-1, h-1 ); 953 g.setColor( MetalLookAndFeel.getControlHighlight() ); 954 g.drawLine( 0, 0, w-2, 0 ); 955 g.drawLine( 0, 0, 0, h-2 ); 956 957 g.translate( -x, -y ); 958 } 959 960 public Insets getBorderInsets(Component c, Insets insets) { 961 insets.set(2, 2, 2, 0); 962 return insets; 963 } 964 } 965 966 /** 967 * Returns a border instance for a Desktop Icon 968 * @since 1.3 969 */ 970 public static Border getDesktopIconBorder() { 971 return new BorderUIResource.CompoundBorderUIResource( 972 new LineBorder(MetalLookAndFeel.getControlDarkShadow(), 1), 973 new MatteBorder (2,2,1,2, MetalLookAndFeel.getControl())); 974 } 975 976 static Border getToolBarRolloverBorder() { 977 if (MetalLookAndFeel.usingOcean()) { 978 return new CompoundBorder( 979 new MetalBorders.ButtonBorder(), 980 new MetalBorders.RolloverMarginBorder()); 981 } 982 return new CompoundBorder(new MetalBorders.RolloverButtonBorder(), 983 new MetalBorders.RolloverMarginBorder()); 984 } 985 986 static Border getToolBarNonrolloverBorder() { 987 if (MetalLookAndFeel.usingOcean()) { 988 new CompoundBorder( 989 new MetalBorders.ButtonBorder(), 990 new MetalBorders.RolloverMarginBorder()); 991 } 992 return new CompoundBorder(new MetalBorders.ButtonBorder(), 993 new MetalBorders.RolloverMarginBorder()); 994 } 995 }