J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 1 | /* |
| 2 | * Copyright 1997-2005 Sun Microsystems, Inc. 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. Sun designates this |
| 8 | * particular file as subject to the "Classpath" exception as provided |
| 9 | * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
| 22 | * CA 95054 USA or visit www.sun.com if you need additional information or |
| 23 | * have any questions. |
| 24 | */ |
| 25 | |
| 26 | package com.sun.java.swing.plaf.motif; |
| 27 | |
| 28 | import sun.swing.SwingUtilities2; |
| 29 | import javax.swing.*; |
| 30 | import javax.swing.border.*; |
| 31 | import javax.swing.plaf.*; |
| 32 | |
| 33 | import java.awt.Color; |
| 34 | import java.awt.Component; |
| 35 | import java.awt.Dimension; |
| 36 | import java.awt.Font; |
| 37 | import java.awt.FontMetrics; |
| 38 | import java.awt.Graphics; |
| 39 | import java.awt.Insets; |
| 40 | import java.awt.Point; |
| 41 | import java.awt.Rectangle; |
| 42 | |
| 43 | import java.io.Serializable; |
| 44 | |
| 45 | /** |
| 46 | * Factory object that can vend Icons appropriate for the basic L & F. |
| 47 | * <p> |
| 48 | * <strong>Warning:</strong> |
| 49 | * Serialized objects of this class will not be compatible with |
| 50 | * future Swing releases. The current serialization support is appropriate |
| 51 | * for short term storage or RMI between applications running the same |
| 52 | * version of Swing. A future release of Swing will provide support for |
| 53 | * long term persistence. |
| 54 | * |
| 55 | * @author Amy Fowler |
| 56 | */ |
| 57 | public class MotifBorders { |
| 58 | |
| 59 | public static class BevelBorder extends AbstractBorder implements UIResource { |
| 60 | private Color darkShadow = UIManager.getColor("controlShadow"); |
| 61 | private Color lightShadow = UIManager.getColor("controlLtHighlight"); |
| 62 | private boolean isRaised; |
| 63 | |
| 64 | public BevelBorder(boolean isRaised, Color darkShadow, Color lightShadow) { |
| 65 | this.isRaised = isRaised; |
| 66 | this.darkShadow = darkShadow; |
| 67 | this.lightShadow = lightShadow; |
| 68 | } |
| 69 | |
| 70 | public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { |
| 71 | g.setColor((isRaised) ? lightShadow : darkShadow); |
| 72 | g.drawLine(x, y, x+w-1, y); // top |
| 73 | g.drawLine(x, y+h-1, x, y+1); // left |
| 74 | |
| 75 | g.setColor((isRaised) ? darkShadow : lightShadow); |
| 76 | g.drawLine(x+1, y+h-1, x+w-1, y+h-1); // bottom |
| 77 | g.drawLine(x+w-1, y+h-1, x+w-1, y+1); // right |
| 78 | } |
| 79 | |
| 80 | public Insets getBorderInsets(Component c, Insets insets) { |
| 81 | insets.set(1, 1, 1, 1); |
| 82 | return insets; |
| 83 | } |
| 84 | |
| 85 | public boolean isOpaque(Component c) { |
| 86 | return true; |
| 87 | } |
| 88 | |
| 89 | } |
| 90 | |
| 91 | |
| 92 | public static class FocusBorder extends AbstractBorder implements UIResource { |
| 93 | private Color focus; |
| 94 | private Color control; |
| 95 | |
| 96 | public FocusBorder(Color control, Color focus) { |
| 97 | this.control = control; |
| 98 | this.focus = focus; |
| 99 | } |
| 100 | |
| 101 | public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { |
| 102 | if (((JComponent)c).hasFocus()) { |
| 103 | g.setColor(focus); |
| 104 | g.drawRect(x, y, w-1, h-1); |
| 105 | } else { |
| 106 | g.setColor(control); |
| 107 | g.drawRect(x, y, w-1, h-1); |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | public Insets getBorderInsets(Component c, Insets insets) { |
| 112 | insets.set(1, 1, 1, 1); |
| 113 | return insets; |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | |
| 118 | public static class ButtonBorder extends AbstractBorder implements UIResource { |
| 119 | protected Color focus = UIManager.getColor("activeCaptionBorder"); |
| 120 | protected Color shadow = UIManager.getColor("Button.shadow"); |
| 121 | protected Color highlight = UIManager.getColor("Button.light"); |
| 122 | protected Color darkShadow; |
| 123 | |
| 124 | public ButtonBorder(Color shadow, Color highlight, Color darkShadow, Color focus) { |
| 125 | this.shadow = shadow; |
| 126 | this.highlight = highlight; |
| 127 | this.darkShadow = darkShadow; |
| 128 | this.focus = focus; |
| 129 | } |
| 130 | |
| 131 | public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) { |
| 132 | boolean isPressed = false; |
| 133 | boolean hasFocus = false; |
| 134 | boolean canBeDefault = false; |
| 135 | boolean isDefault = false; |
| 136 | |
| 137 | if (c instanceof AbstractButton) { |
| 138 | AbstractButton b = (AbstractButton)c; |
| 139 | ButtonModel model = b.getModel(); |
| 140 | |
| 141 | isPressed = (model.isArmed() && model.isPressed()); |
| 142 | hasFocus = (model.isArmed() && isPressed) || |
| 143 | (b.isFocusPainted() && b.hasFocus()); |
| 144 | if (b instanceof JButton) { |
| 145 | canBeDefault = ((JButton)b).isDefaultCapable(); |
| 146 | isDefault = ((JButton)b).isDefaultButton(); |
| 147 | } |
| 148 | } |
| 149 | int bx1 = x+1; |
| 150 | int by1 = y+1; |
| 151 | int bx2 = x+w-2; |
| 152 | int by2 = y+h-2; |
| 153 | |
| 154 | if (canBeDefault) { |
| 155 | if (isDefault) { |
| 156 | g.setColor(shadow); |
| 157 | g.drawLine(x+3, y+3, x+3, y+h-4); |
| 158 | g.drawLine(x+3, y+3, x+w-4, y+3); |
| 159 | |
| 160 | g.setColor(highlight); |
| 161 | g.drawLine(x+4, y+h-4, x+w-4, y+h-4); |
| 162 | g.drawLine(x+w-4, y+3, x+w-4, y+h-4); |
| 163 | } |
| 164 | bx1 +=6; |
| 165 | by1 += 6; |
| 166 | bx2 -= 6; |
| 167 | by2 -= 6; |
| 168 | } |
| 169 | |
| 170 | if (hasFocus) { |
| 171 | g.setColor(focus); |
| 172 | if (isDefault) { |
| 173 | g.drawRect(x, y, w-1, h-1); |
| 174 | } else { |
| 175 | g.drawRect(bx1-1, by1-1, bx2-bx1+2, by2-by1+2); |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | g.setColor(isPressed? shadow : highlight); |
| 180 | g.drawLine(bx1, by1, bx2, by1); |
| 181 | g.drawLine(bx1, by1, bx1, by2); |
| 182 | |
| 183 | g.setColor(isPressed? highlight : shadow); |
| 184 | g.drawLine(bx2, by1+1, bx2, by2); |
| 185 | g.drawLine(bx1+1, by2, bx2, by2); |
| 186 | } |
| 187 | |
| 188 | public Insets getBorderInsets(Component c, Insets insets) { |
| 189 | int thickness = (c instanceof JButton && ((JButton)c).isDefaultCapable())? 8 : 2; |
| 190 | insets.set(thickness, thickness, thickness, thickness); |
| 191 | return insets; |
| 192 | } |
| 193 | |
| 194 | } |
| 195 | |
| 196 | public static class ToggleButtonBorder extends ButtonBorder { |
| 197 | |
| 198 | public ToggleButtonBorder(Color shadow, Color highlight, Color darkShadow, Color focus) { |
| 199 | super(shadow, highlight, darkShadow, focus); |
| 200 | } |
| 201 | |
| 202 | public void paintBorder(Component c, Graphics g, int x, int y, |
| 203 | int width, int height) { |
| 204 | if (c instanceof AbstractButton) { |
| 205 | AbstractButton b = (AbstractButton)c; |
| 206 | ButtonModel model = b.getModel(); |
| 207 | |
| 208 | if (model.isArmed() && model.isPressed() || model.isSelected()) { |
| 209 | drawBezel(g, x, y, width, height, |
| 210 | (model.isPressed() || model.isSelected()), |
| 211 | b.isFocusPainted() && b.hasFocus(), shadow, highlight, darkShadow, focus); |
| 212 | } else { |
| 213 | drawBezel(g, x, y, width, height, |
| 214 | false, b.isFocusPainted() && b.hasFocus(), |
| 215 | shadow, highlight, darkShadow, focus); |
| 216 | } |
| 217 | } else { |
| 218 | drawBezel(g, x, y, width, height, false, false, |
| 219 | shadow, highlight, darkShadow, focus); |
| 220 | } |
| 221 | } |
| 222 | |
| 223 | public Insets getBorderInsets(Component c, Insets insets) { |
| 224 | insets.set(2, 2, 3, 3); |
| 225 | return insets; |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | public static class MenuBarBorder extends ButtonBorder { |
| 230 | |
| 231 | public MenuBarBorder(Color shadow, Color highlight, Color darkShadow, Color focus) { |
| 232 | super(shadow, highlight, darkShadow, focus); |
| 233 | } |
| 234 | |
| 235 | public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { |
| 236 | JMenuBar menuBar = (JMenuBar)c; |
| 237 | if (menuBar.isBorderPainted() == true) { |
| 238 | // this draws the MenuBar border |
| 239 | Dimension size = menuBar.getSize(); |
| 240 | drawBezel(g,x,y,size.width,size.height,false,false, |
| 241 | shadow, highlight, darkShadow, focus); |
| 242 | } |
| 243 | } |
| 244 | |
| 245 | public Insets getBorderInsets(Component c, Insets insets) { |
| 246 | insets.set(6, 6, 6, 6); |
| 247 | return insets; |
| 248 | } |
| 249 | } |
| 250 | |
| 251 | public static class FrameBorder extends AbstractBorder implements UIResource { |
| 252 | |
| 253 | JComponent jcomp; |
| 254 | Color frameHighlight; |
| 255 | Color frameColor; |
| 256 | Color frameShadow; |
| 257 | |
| 258 | // The width of the border |
| 259 | public final static int BORDER_SIZE = 5; |
| 260 | |
| 261 | /** Constructs an FrameBorder for the JComponent <b>comp</b>. |
| 262 | */ |
| 263 | public FrameBorder(JComponent comp) { |
| 264 | jcomp = comp; |
| 265 | } |
| 266 | |
| 267 | /** Sets the FrameBorder's JComponent. |
| 268 | */ |
| 269 | public void setComponent(JComponent comp) { |
| 270 | jcomp = comp; |
| 271 | } |
| 272 | |
| 273 | /** Returns the FrameBorder's JComponent. |
| 274 | * @see #setComponent |
| 275 | */ |
| 276 | public JComponent component() { |
| 277 | return jcomp; |
| 278 | } |
| 279 | |
| 280 | protected Color getFrameHighlight() { |
| 281 | return frameHighlight; |
| 282 | } |
| 283 | |
| 284 | protected Color getFrameColor() { |
| 285 | return frameColor; |
| 286 | } |
| 287 | |
| 288 | protected Color getFrameShadow() { |
| 289 | return frameShadow; |
| 290 | } |
| 291 | |
| 292 | public Insets getBorderInsets(Component c, Insets newInsets) { |
| 293 | newInsets.set(BORDER_SIZE, BORDER_SIZE, BORDER_SIZE, BORDER_SIZE); |
| 294 | return newInsets; |
| 295 | } |
| 296 | |
| 297 | /** Draws the FrameBorder's top border. |
| 298 | */ |
| 299 | protected boolean drawTopBorder(Component c, Graphics g, |
| 300 | int x, int y, int width, int height) { |
| 301 | Rectangle titleBarRect = new Rectangle(x, y, width, BORDER_SIZE); |
| 302 | if (!g.getClipBounds().intersects(titleBarRect)) { |
| 303 | return false; |
| 304 | } |
| 305 | |
| 306 | int maxX = width - 1; |
| 307 | int maxY = BORDER_SIZE - 1; |
| 308 | |
| 309 | // Draw frame |
| 310 | g.setColor(frameColor); |
| 311 | g.drawLine(x, y + 2, maxX - 2, y + 2); |
| 312 | g.drawLine(x, y + 3, maxX - 2, y + 3); |
| 313 | g.drawLine(x, y + 4, maxX - 2, y + 4); |
| 314 | |
| 315 | // Draw highlights |
| 316 | g.setColor(frameHighlight); |
| 317 | g.drawLine(x, y, maxX, y); |
| 318 | g.drawLine(x, y + 1, maxX, y + 1); |
| 319 | g.drawLine(x, y + 2, x, y + 4); |
| 320 | g.drawLine(x + 1, y + 2, x + 1, y + 4); |
| 321 | |
| 322 | // Draw shadows |
| 323 | g.setColor(frameShadow); |
| 324 | g.drawLine(x + 4, y + 4, maxX - 4, y + 4); |
| 325 | g.drawLine(maxX, y + 1, maxX, maxY); |
| 326 | g.drawLine(maxX - 1, y + 2, maxX - 1, maxY); |
| 327 | |
| 328 | return true; |
| 329 | } |
| 330 | |
| 331 | /** Draws the FrameBorder's left border. |
| 332 | */ |
| 333 | protected boolean drawLeftBorder(Component c, Graphics g, int x, int y, |
| 334 | int width, int height) { |
| 335 | Rectangle borderRect = |
| 336 | new Rectangle(0, 0, getBorderInsets(c).left, height); |
| 337 | if (!g.getClipBounds().intersects(borderRect)) { |
| 338 | return false; |
| 339 | } |
| 340 | |
| 341 | int startY = BORDER_SIZE; |
| 342 | |
| 343 | g.setColor(frameHighlight); |
| 344 | g.drawLine(x, startY, x, height - 1); |
| 345 | g.drawLine(x + 1, startY, x + 1, height - 2); |
| 346 | |
| 347 | g.setColor(frameColor); |
| 348 | g.fillRect(x + 2, startY, x + 2, height - 3); |
| 349 | |
| 350 | g.setColor(frameShadow); |
| 351 | g.drawLine(x + 4, startY, x + 4, height - 5); |
| 352 | |
| 353 | return true; |
| 354 | } |
| 355 | |
| 356 | /** Draws the FrameBorder's right border. |
| 357 | */ |
| 358 | protected boolean drawRightBorder(Component c, Graphics g, int x, int y, |
| 359 | int width, int height) { |
| 360 | Rectangle borderRect = new Rectangle( |
| 361 | width - getBorderInsets(c).right, 0, |
| 362 | getBorderInsets(c).right, height); |
| 363 | if (!g.getClipBounds().intersects(borderRect)) { |
| 364 | return false; |
| 365 | } |
| 366 | |
| 367 | int startX = width - getBorderInsets(c).right; |
| 368 | int startY = BORDER_SIZE; |
| 369 | |
| 370 | g.setColor(frameColor); |
| 371 | g.fillRect(startX + 1, startY, 2, height - 1); |
| 372 | |
| 373 | g.setColor(frameShadow); |
| 374 | g.fillRect(startX + 3, startY, 2, height - 1); |
| 375 | |
| 376 | g.setColor(frameHighlight); |
| 377 | g.drawLine(startX, startY, startX, height - 1); |
| 378 | |
| 379 | return true; |
| 380 | } |
| 381 | |
| 382 | /** Draws the FrameBorder's bottom border. |
| 383 | */ |
| 384 | protected boolean drawBottomBorder(Component c, Graphics g, int x, int y, |
| 385 | int width, int height) { |
| 386 | Rectangle borderRect; |
| 387 | int marginHeight, startY; |
| 388 | |
| 389 | borderRect = new Rectangle(0, height - getBorderInsets(c).bottom, |
| 390 | width, getBorderInsets(c).bottom); |
| 391 | if (!g.getClipBounds().intersects(borderRect)) { |
| 392 | return false; |
| 393 | } |
| 394 | |
| 395 | startY = height - getBorderInsets(c).bottom; |
| 396 | |
| 397 | g.setColor(frameShadow); |
| 398 | g.drawLine(x + 1, height - 1, width - 1, height - 1); |
| 399 | g.drawLine(x + 2, height - 2, width - 2, height - 2); |
| 400 | |
| 401 | g.setColor(frameColor); |
| 402 | g.fillRect(x + 2, startY + 1, width - 4, 2); |
| 403 | |
| 404 | g.setColor(frameHighlight); |
| 405 | g.drawLine(x + 5, startY, width - 5, startY); |
| 406 | |
| 407 | return true; |
| 408 | } |
| 409 | |
| 410 | // Returns true if the associated component has focus. |
| 411 | protected boolean isActiveFrame() { |
| 412 | return jcomp.hasFocus(); |
| 413 | } |
| 414 | |
| 415 | /** Draws the FrameBorder in the given Rect. Calls |
| 416 | * <b>drawTitleBar</b>, <b>drawLeftBorder</b>, <b>drawRightBorder</b> and |
| 417 | * <b>drawBottomBorder</b>. |
| 418 | */ |
| 419 | public void paintBorder(Component c, Graphics g, |
| 420 | int x, int y, int width, int height) { |
| 421 | if (isActiveFrame()) { |
| 422 | frameColor = UIManager.getColor("activeCaptionBorder"); |
| 423 | } else { |
| 424 | frameColor = UIManager.getColor("inactiveCaptionBorder"); |
| 425 | } |
| 426 | frameHighlight = frameColor.brighter(); |
| 427 | frameShadow = frameColor.darker().darker(); |
| 428 | |
| 429 | drawTopBorder(c, g, x, y, width, height); |
| 430 | drawLeftBorder(c, g, x, y, width, height); |
| 431 | drawRightBorder(c, g, x, y, width, height); |
| 432 | drawBottomBorder(c, g, x, y, width, height); |
| 433 | } |
| 434 | } |
| 435 | |
| 436 | public static class InternalFrameBorder extends FrameBorder { |
| 437 | |
| 438 | JInternalFrame frame; |
| 439 | |
| 440 | // The size of the bounding box for Motif frame corners. |
| 441 | public final static int CORNER_SIZE = 24; |
| 442 | |
| 443 | /** Constructs an InternalFrameBorder for the InternalFrame |
| 444 | * <b>aFrame</b>. |
| 445 | */ |
| 446 | public InternalFrameBorder(JInternalFrame aFrame) { |
| 447 | super(aFrame); |
| 448 | frame = aFrame; |
| 449 | } |
| 450 | |
| 451 | /** Sets the InternalFrameBorder's InternalFrame. |
| 452 | */ |
| 453 | public void setFrame(JInternalFrame aFrame) { |
| 454 | frame = aFrame; |
| 455 | } |
| 456 | |
| 457 | /** Returns the InternalFrameBorder's InternalFrame. |
| 458 | * @see #setFrame |
| 459 | */ |
| 460 | public JInternalFrame frame() { |
| 461 | return frame; |
| 462 | } |
| 463 | |
| 464 | /** Returns the width of the InternalFrameBorder's resize controls, |
| 465 | * appearing along the InternalFrameBorder's bottom border. Clicking |
| 466 | * and dragging within these controls lets the user change both the |
| 467 | * InternalFrame's width and height, while dragging between the controls |
| 468 | * constrains resizing to just the vertical dimension. Override this |
| 469 | * method if you implement your own bottom border painting and use a |
| 470 | * resize control with a different size. |
| 471 | */ |
| 472 | public int resizePartWidth() { |
| 473 | if (!frame.isResizable()) { |
| 474 | return 0; |
| 475 | } |
| 476 | return FrameBorder.BORDER_SIZE; |
| 477 | } |
| 478 | |
| 479 | /** Draws the InternalFrameBorder's top border. |
| 480 | */ |
| 481 | protected boolean drawTopBorder(Component c, Graphics g, |
| 482 | int x, int y, int width, int height) { |
| 483 | if (super.drawTopBorder(c, g, x, y, width, height) && |
| 484 | frame.isResizable()) { |
| 485 | g.setColor(getFrameShadow()); |
| 486 | g.drawLine(CORNER_SIZE - 1, y + 1, CORNER_SIZE - 1, y + 4); |
| 487 | g.drawLine(width - CORNER_SIZE - 1, y + 1, |
| 488 | width - CORNER_SIZE - 1, y + 4); |
| 489 | |
| 490 | g.setColor(getFrameHighlight()); |
| 491 | g.drawLine(CORNER_SIZE, y, CORNER_SIZE, y + 4); |
| 492 | g.drawLine(width - CORNER_SIZE, y, width - CORNER_SIZE, y + 4); |
| 493 | return true; |
| 494 | } |
| 495 | return false; |
| 496 | } |
| 497 | |
| 498 | /** Draws the InternalFrameBorder's left border. |
| 499 | */ |
| 500 | protected boolean drawLeftBorder(Component c, Graphics g, int x, int y, |
| 501 | int width, int height) { |
| 502 | if (super.drawLeftBorder(c, g, x, y, width, height) && |
| 503 | frame.isResizable()) { |
| 504 | g.setColor(getFrameHighlight()); |
| 505 | int topY = y + CORNER_SIZE; |
| 506 | g.drawLine(x, topY, x + 4, topY); |
| 507 | int bottomY = height - CORNER_SIZE; |
| 508 | g.drawLine(x + 1, bottomY, x + 5, bottomY); |
| 509 | g.setColor(getFrameShadow()); |
| 510 | g.drawLine(x + 1, topY - 1, x + 5, topY - 1); |
| 511 | g.drawLine(x + 1, bottomY - 1, x + 5, bottomY - 1); |
| 512 | return true; |
| 513 | } |
| 514 | return false; |
| 515 | } |
| 516 | |
| 517 | /** Draws the InternalFrameBorder's right border. |
| 518 | */ |
| 519 | protected boolean drawRightBorder(Component c, Graphics g, int x, int y, |
| 520 | int width, int height) { |
| 521 | if (super.drawRightBorder(c, g, x, y, width, height) && |
| 522 | frame.isResizable()) { |
| 523 | int startX = width - getBorderInsets(c).right; |
| 524 | g.setColor(getFrameHighlight()); |
| 525 | int topY = y + CORNER_SIZE; |
| 526 | g.drawLine(startX, topY, width - 2, topY); |
| 527 | int bottomY = height - CORNER_SIZE; |
| 528 | g.drawLine(startX + 1, bottomY, startX + 3, bottomY); |
| 529 | g.setColor(getFrameShadow()); |
| 530 | g.drawLine(startX + 1, topY - 1, width - 2, topY - 1); |
| 531 | g.drawLine(startX + 1, bottomY - 1, startX + 3, bottomY - 1); |
| 532 | return true; |
| 533 | } |
| 534 | return false; |
| 535 | } |
| 536 | |
| 537 | /** Draws the InternalFrameBorder's bottom border. |
| 538 | */ |
| 539 | protected boolean drawBottomBorder(Component c, Graphics g, int x, int y, |
| 540 | int width, int height) { |
| 541 | if (super.drawBottomBorder(c, g, x, y, width, height) && |
| 542 | frame.isResizable()) { |
| 543 | int startY = height - getBorderInsets(c).bottom; |
| 544 | |
| 545 | g.setColor(getFrameShadow()); |
| 546 | g.drawLine(CORNER_SIZE - 1, startY + 1, |
| 547 | CORNER_SIZE - 1, height - 1); |
| 548 | g.drawLine(width - CORNER_SIZE, startY + 1, |
| 549 | width - CORNER_SIZE, height - 1); |
| 550 | |
| 551 | g.setColor(getFrameHighlight()); |
| 552 | g.drawLine(CORNER_SIZE, startY, CORNER_SIZE, height - 2); |
| 553 | g.drawLine(width - CORNER_SIZE + 1, startY, |
| 554 | width - CORNER_SIZE + 1, height - 2); |
| 555 | return true; |
| 556 | } |
| 557 | return false; |
| 558 | } |
| 559 | |
| 560 | // Returns true if the associated internal frame has focus. |
| 561 | protected boolean isActiveFrame() { |
| 562 | return frame.isSelected(); |
| 563 | } |
| 564 | } |
| 565 | |
| 566 | public static void drawBezel(Graphics g, int x, int y, int w, int h, |
| 567 | boolean isPressed, boolean hasFocus, |
| 568 | Color shadow, Color highlight, |
| 569 | Color darkShadow, Color focus) { |
| 570 | |
| 571 | Color oldColor = g.getColor(); |
| 572 | g.translate(x, y); |
| 573 | |
| 574 | if (isPressed) { |
| 575 | if (hasFocus){ |
| 576 | g.setColor(focus); |
| 577 | g.drawRect(0, 0, w-1, h-1); |
| 578 | } |
| 579 | g.setColor(shadow); // inner border |
| 580 | g.drawRect(1, 1, w-3, h-3); |
| 581 | |
| 582 | g.setColor(highlight); // inner 3D border |
| 583 | g.drawLine(2, h-3, w-3, h-3); |
| 584 | g.drawLine(w-3, 2, w-3, h-4); |
| 585 | |
| 586 | } else { |
| 587 | if (hasFocus) { |
| 588 | g.setColor(focus); |
| 589 | g.drawRect(0, 0, w-1, h-1); |
| 590 | |
| 591 | g.setColor(highlight); // inner 3D border |
| 592 | g.drawLine(1, 1, 1, h-3); |
| 593 | g.drawLine(2, 1, w-4, 1); |
| 594 | |
| 595 | g.setColor(shadow); |
| 596 | g.drawLine(2, h-3, w-3, h-3); |
| 597 | g.drawLine(w-3, 1, w-3, h-4); |
| 598 | |
| 599 | g.setColor(darkShadow); // black drop shadow __| |
| 600 | g.drawLine(1, h-2, w-2, h-2); |
| 601 | g.drawLine(w-2, h-2, w-2, 1); |
| 602 | } else { |
| 603 | g.setColor(highlight); // inner 3D border |
| 604 | g.drawLine(1,1,1,h-3); |
| 605 | g.drawLine(2,1,w-4,1); |
| 606 | g.setColor(shadow); |
| 607 | g.drawLine(2,h-3,w-3,h-3); |
| 608 | g.drawLine(w-3,1,w-3,h-4); |
| 609 | |
| 610 | g.setColor(darkShadow); // black drop shadow __| |
| 611 | g.drawLine(1,h-2,w-2,h-2); |
| 612 | g.drawLine(w-2,h-2,w-2,0); |
| 613 | |
| 614 | } |
| 615 | g.translate(-x, -y); |
| 616 | } |
| 617 | g.setColor(oldColor); |
| 618 | } |
| 619 | |
| 620 | public static class MotifPopupMenuBorder extends AbstractBorder implements UIResource { |
| 621 | protected Font font; |
| 622 | protected Color background; |
| 623 | protected Color foreground; |
| 624 | protected Color shadowColor; |
| 625 | protected Color highlightColor; |
| 626 | |
| 627 | // Space between the border and text |
| 628 | static protected final int TEXT_SPACING = 2; |
| 629 | |
| 630 | // Space for the separator under the title |
| 631 | static protected final int GROOVE_HEIGHT = 2; |
| 632 | |
| 633 | /** |
| 634 | * Creates a MotifPopupMenuBorder instance |
| 635 | * |
| 636 | */ |
| 637 | public MotifPopupMenuBorder( |
| 638 | Font titleFont, |
| 639 | Color bgColor, |
| 640 | Color fgColor, |
| 641 | Color shadow, |
| 642 | Color highlight) { |
| 643 | this.font = titleFont; |
| 644 | this.background = bgColor; |
| 645 | this.foreground = fgColor; |
| 646 | this.shadowColor = shadow; |
| 647 | this.highlightColor = highlight; |
| 648 | } |
| 649 | |
| 650 | /** |
| 651 | * Paints the border for the specified component with the |
| 652 | * specified position and size. |
| 653 | * @param c the component for which this border is being painted |
| 654 | * @param g the paint graphics |
| 655 | * @param x the x position of the painted border |
| 656 | * @param y the y position of the painted border |
| 657 | * @param width the width of the painted border |
| 658 | * @param height the height of the painted border |
| 659 | */ |
| 660 | public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { |
| 661 | |
| 662 | Font origFont = g.getFont(); |
| 663 | Color origColor = g.getColor(); |
| 664 | JPopupMenu popup = (JPopupMenu)c; |
| 665 | |
| 666 | String title = popup.getLabel(); |
| 667 | if (title == null) { |
| 668 | return; |
| 669 | } |
| 670 | |
| 671 | g.setFont(font); |
| 672 | |
| 673 | FontMetrics fm = SwingUtilities2.getFontMetrics(popup, g, font); |
| 674 | int fontHeight = fm.getHeight(); |
| 675 | int descent = fm.getDescent(); |
| 676 | int ascent = fm.getAscent(); |
| 677 | Point textLoc = new Point(); |
| 678 | int stringWidth = SwingUtilities2.stringWidth(popup, fm, |
| 679 | title); |
| 680 | |
| 681 | textLoc.y = y + ascent + TEXT_SPACING; |
| 682 | textLoc.x = x + ((width - stringWidth) / 2); |
| 683 | |
| 684 | g.setColor(background); |
| 685 | g.fillRect(textLoc.x - TEXT_SPACING, textLoc.y - (fontHeight-descent), |
| 686 | stringWidth + (2 * TEXT_SPACING), fontHeight - descent); |
| 687 | g.setColor(foreground); |
| 688 | SwingUtilities2.drawString(popup, g, title, textLoc.x, textLoc.y); |
| 689 | |
| 690 | MotifGraphicsUtils.drawGroove(g, x, textLoc.y + TEXT_SPACING, |
| 691 | width, GROOVE_HEIGHT, |
| 692 | shadowColor, highlightColor); |
| 693 | |
| 694 | g.setFont(origFont); |
| 695 | g.setColor(origColor); |
| 696 | } |
| 697 | |
| 698 | /** |
| 699 | * Reinitialize the insets parameter with this Border's current Insets. |
| 700 | * @param c the component for which this border insets value applies |
| 701 | * @param insets the object to be reinitialized |
| 702 | */ |
| 703 | public Insets getBorderInsets(Component c, Insets insets) { |
| 704 | FontMetrics fm; |
| 705 | int descent = 0; |
| 706 | int ascent = 16; |
| 707 | |
| 708 | String title = ((JPopupMenu)c).getLabel(); |
| 709 | if (title == null) { |
| 710 | insets.left = insets.top = insets.right = insets.bottom = 0; |
| 711 | return insets; |
| 712 | } |
| 713 | |
| 714 | fm = c.getFontMetrics(font); |
| 715 | |
| 716 | if(fm != null) { |
| 717 | descent = fm.getDescent(); |
| 718 | ascent = fm.getAscent(); |
| 719 | } |
| 720 | |
| 721 | insets.top += ascent + descent + TEXT_SPACING + GROOVE_HEIGHT; |
| 722 | return insets; |
| 723 | } |
| 724 | |
| 725 | } |
| 726 | |
| 727 | } |