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