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