1. /*
  2. * @(#)MetalBorders.java 1.18 00/02/02
  3. *
  4. * Copyright 1998-2000 Sun Microsystems, Inc. All Rights Reserved.
  5. *
  6. * This software is the proprietary information of Sun Microsystems, Inc.
  7. * Use is subject to license terms.
  8. *
  9. */
  10. package javax.swing.plaf.metal;
  11. import javax.swing.*;
  12. import javax.swing.border.*;
  13. import javax.swing.plaf.*;
  14. import javax.swing.plaf.basic.BasicBorders;
  15. import javax.swing.text.JTextComponent;
  16. import java.awt.Component;
  17. import java.awt.Insets;
  18. import java.awt.Dimension;
  19. import java.awt.Rectangle;
  20. import java.awt.Color;
  21. import java.awt.Graphics;
  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.18 02/02/00
  27. */
  28. public class MetalBorders {
  29. public static class Flush3DBorder extends AbstractBorder implements UIResource{
  30. private static final Insets insets = new Insets(2, 2, 2, 2);
  31. public void paintBorder(Component c, Graphics g, int x, int y,
  32. int w, int h) {
  33. if (c.isEnabled()) {
  34. MetalUtils.drawFlush3DBorder(g, x, y, w, h);
  35. } else {
  36. MetalUtils.drawDisabledBorder(g, x, y, w, h);
  37. }
  38. }
  39. public Insets getBorderInsets(Component c) {
  40. return insets;
  41. }
  42. }
  43. public static class ButtonBorder extends AbstractBorder implements UIResource {
  44. protected static Insets borderInsets = new Insets( 3, 3, 3, 3 );
  45. public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
  46. JButton button = (JButton)c;
  47. ButtonModel model = button.getModel();
  48. if ( model.isEnabled() ) {
  49. if ( model.isPressed() && model.isArmed() ) {
  50. MetalUtils.drawPressed3DBorder( g, x, y, w, h );
  51. }
  52. else {
  53. if (button.isDefaultButton()) {
  54. MetalUtils.drawDefaultButtonBorder( g, x, y, w, h, button.hasFocus() && false );
  55. } else {
  56. MetalUtils.drawButtonBorder( g, x, y, w, h, button.hasFocus() && false);
  57. }
  58. }
  59. } else { // disabled state
  60. MetalUtils.drawDisabledBorder( g, x, y, w-1, h-1 );
  61. }
  62. }
  63. public Insets getBorderInsets( Component c ) {
  64. return borderInsets;
  65. }
  66. }
  67. public static class InternalFrameBorder extends AbstractBorder implements UIResource {
  68. private static final Insets insets = new Insets(5, 5, 5, 5);
  69. private static final int corner = 14;
  70. public void paintBorder(Component c, Graphics g, int x, int y,
  71. int w, int h) {
  72. Color background;
  73. Color highlight;
  74. Color shadow;
  75. if (c instanceof JInternalFrame && ((JInternalFrame)c).isSelected()) {
  76. background = MetalLookAndFeel.getPrimaryControlDarkShadow();
  77. highlight = MetalLookAndFeel.getPrimaryControlShadow();
  78. shadow = MetalLookAndFeel.getPrimaryControlInfo();
  79. } else {
  80. background = MetalLookAndFeel.getControlDarkShadow();
  81. highlight = MetalLookAndFeel.getControlShadow();
  82. shadow = MetalLookAndFeel.getControlInfo();
  83. }
  84. g.setColor(background);
  85. // Draw outermost lines
  86. g.drawLine( 1, 0, w-2, 0);
  87. g.drawLine( 0, 1, 0, h-2);
  88. g.drawLine( w-1, 1, w-1, h-2);
  89. g.drawLine( 1, h-1, w-2, h-1);
  90. // Draw the bulk of the border
  91. for (int i = 1; i < 5; i++) {
  92. g.drawRect(x+i,y+i,w-(i*2)-1, h-(i*2)-1);
  93. }
  94. g.setColor(highlight);
  95. // Draw the Long highlight lines
  96. g.drawLine( corner+1, 3, w-corner, 3);
  97. g.drawLine( 3, corner+1, 3, h-corner);
  98. g.drawLine( w-2, corner+1, w-2, h-corner);
  99. g.drawLine( corner+1, h-2, w-corner, h-2);
  100. g.setColor(shadow);
  101. // Draw the Long shadow lines
  102. g.drawLine( corner, 2, w-corner-1, 2);
  103. g.drawLine( 2, corner, 2, h-corner-1);
  104. g.drawLine( w-3, corner, w-3, h-corner-1);
  105. g.drawLine( corner, h-3, w-corner-1, h-3);
  106. }
  107. public Insets getBorderInsets(Component c) {
  108. return insets;
  109. }
  110. }
  111. /**
  112. * Border for a Palatte.
  113. * @since 1.3
  114. */
  115. public static class PaletteBorder extends AbstractBorder implements UIResource {
  116. private static final Insets insets = new Insets(1, 1, 1, 1);
  117. int titleHeight = 0;
  118. public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
  119. g.translate(x,y);
  120. g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
  121. g.drawLine(0, 1, 0, h-2);
  122. g.drawLine(1, h-1, w-2, h-1);
  123. g.drawLine(w-1, 1, w-1, h-2);
  124. g.drawLine( 1, 0, w-2, 0);
  125. g.drawRect(1,1, w-3, h-3);
  126. /*
  127. titleHeight = UIManager.getInt("JInternalFrame.paletteTitleHeight");
  128. g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
  129. g.drawLine(0, titleHeight, 0, h-2);
  130. g.drawLine(1, h-1, w-2, h-1);
  131. g.drawLine(w-1, titleHeight, w-1, h-2);
  132. g.setColor(MetalLookAndFeel.getPrimaryControl());
  133. g.drawLine(1,0, w-2, 0);
  134. g.drawLine(0, 1, 0, titleHeight-1);
  135. g.drawLine(w-1, 1, w-1, titleHeight-1);
  136. */
  137. g.translate(-x,-y);
  138. }
  139. public Insets getBorderInsets(Component c) {
  140. return insets;
  141. }
  142. }
  143. public static class OptionDialogBorder extends AbstractBorder implements UIResource {
  144. private static final Insets insets = new Insets(3, 3, 3, 3);
  145. int titleHeight = 0;
  146. public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
  147. g.translate(x,y);
  148. g.setColor(MetalLookAndFeel.getPrimaryControlDarkShadow());
  149. // Draw outermost lines
  150. g.drawLine( 1, 0, w-2, 0);
  151. g.drawLine( 0, 1, 0, h-2);
  152. g.drawLine( w-1, 1, w-1, h-2);
  153. g.drawLine( 1, h-1, w-2, h-1);
  154. // Draw the bulk of the border
  155. for (int i = 1; i < 3; i++) {
  156. g.drawRect(i, i, w-(i*2)-1, h-(i*2)-1);
  157. }
  158. g.translate(-x,-y);
  159. }
  160. public Insets getBorderInsets(Component c) {
  161. return insets;
  162. }
  163. }
  164. public static class MenuBarBorder extends AbstractBorder implements UIResource {
  165. protected static Insets borderInsets = new Insets( 1, 0, 1, 0 );
  166. public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
  167. g.translate( x, y );
  168. g.setColor( MetalLookAndFeel.getControlShadow() );
  169. g.drawLine( 0, h-1, w, h-1 );
  170. g.translate( -x, -y );
  171. }
  172. public Insets getBorderInsets( Component c ) {
  173. return borderInsets;
  174. }
  175. }
  176. public static class MenuItemBorder extends AbstractBorder implements UIResource {
  177. protected static Insets borderInsets = new Insets( 2, 2, 2, 2 );
  178. public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
  179. JMenuItem b = (JMenuItem) c;
  180. ButtonModel model = b.getModel();
  181. g.translate( x, y );
  182. if ( c.getParent() instanceof JMenuBar ) {
  183. if ( model.isArmed() || model.isSelected() ) {
  184. g.setColor( MetalLookAndFeel.getControlDarkShadow() );
  185. g.drawLine( 0, 0, w - 2, 0 );
  186. g.drawLine( 0, 0, 0, h - 1 );
  187. g.drawLine( w - 2, 2, w - 2, h - 1 );
  188. g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
  189. g.drawLine( w - 1, 1, w - 1, h - 1 );
  190. g.setColor( MetalLookAndFeel.getMenuBackground() );
  191. g.drawLine( w - 1, 0, w - 1, 0 );
  192. }
  193. } else {
  194. if ( model.isArmed() || ( c instanceof JMenu && model.isSelected() ) ) {
  195. g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() );
  196. g.drawLine( 0, 0, w - 1, 0 );
  197. g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
  198. g.drawLine( 0, h - 1, w - 1, h - 1 );
  199. } else {
  200. g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
  201. g.drawLine( 0, 0, 0, h - 1 );
  202. }
  203. }
  204. g.translate( -x, -y );
  205. }
  206. public Insets getBorderInsets( Component c ) {
  207. return borderInsets;
  208. }
  209. }
  210. public static class PopupMenuBorder extends AbstractBorder implements UIResource {
  211. protected static Insets borderInsets = new Insets( 3, 1, 2, 1 );
  212. public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
  213. g.translate( x, y );
  214. g.setColor( MetalLookAndFeel.getPrimaryControlDarkShadow() );
  215. g.drawRect( 0, 0, w - 1, h - 1 );
  216. g.setColor( MetalLookAndFeel.getPrimaryControlHighlight() );
  217. g.drawLine( 1, 1, w - 2, 1 );
  218. g.drawLine( 1, 2, 1, 2 );
  219. g.drawLine( 1, h - 2, 1, h - 2 );
  220. g.translate( -x, -y );
  221. }
  222. public Insets getBorderInsets( Component c ) {
  223. return borderInsets;
  224. }
  225. }
  226. public static class RolloverButtonBorder extends ButtonBorder {
  227. public void paintBorder( Component c, Graphics g, int x, int y, int w, int h ) {
  228. AbstractButton b = (AbstractButton) c;
  229. ButtonModel model = b.getModel();
  230. if ( model.isRollover() && !( model.isPressed() && !model.isArmed() ) ) {
  231. super.paintBorder( c, g, x, y, w, h );
  232. }
  233. }
  234. }
  235. public static class ToolBarBorder extends AbstractBorder implements UIResource, SwingConstants
  236. {
  237. protected MetalBumps bumps = new MetalBumps( 10, 10,
  238. MetalLookAndFeel.getControlHighlight(),
  239. MetalLookAndFeel.getControlDarkShadow(),
  240. MetalLookAndFeel.getMenuBackground() );
  241. public void paintBorder( Component c, Graphics g, int x, int y, int w, int h )
  242. {
  243. g.translate( x, y );
  244. if ( ((JToolBar) c).isFloatable() )
  245. {
  246. if ( ((JToolBar) c).getOrientation() == HORIZONTAL )
  247. {
  248. bumps.setBumpArea( 10, c.getSize().height - 4 );
  249. if( MetalUtils.isLeftToRight(c) ) {
  250. bumps.paintIcon( c, g, 2, 2 );
  251. } else {
  252. bumps.paintIcon( c, g, c.getBounds().width-12, 2 );
  253. }
  254. }
  255. else // vertical
  256. {
  257. bumps.setBumpArea( c.getSize().width - 4, 10 );
  258. bumps.paintIcon( c, g, 2, 2 );
  259. }
  260. }
  261. g.translate( -x, -y );
  262. }
  263. public Insets getBorderInsets( Component c )
  264. {
  265. Insets borderInsets = new Insets( 2, 2, 2, 2 );
  266. if ( ((JToolBar) c).isFloatable() )
  267. {
  268. if ( ((JToolBar) c).getOrientation() == HORIZONTAL )
  269. {
  270. borderInsets.left = 16;
  271. }
  272. else // vertical
  273. {
  274. borderInsets.top = 16;
  275. }
  276. }
  277. Insets margin = ((JToolBar) c).getMargin();
  278. if ( margin != null )
  279. {
  280. borderInsets.left += margin.left;
  281. borderInsets.top += margin.top;
  282. borderInsets.right += margin.right;
  283. borderInsets.bottom += margin.bottom;
  284. }
  285. return borderInsets;
  286. }
  287. }
  288. private static Border buttonBorder;
  289. /**
  290. * Returns a border instance for a JButton
  291. * @since 1.3
  292. */
  293. public static Border getButtonBorder() {
  294. if (buttonBorder == null) {
  295. buttonBorder = new BorderUIResource.CompoundBorderUIResource(
  296. new MetalBorders.ButtonBorder(),
  297. new BasicBorders.MarginBorder());
  298. }
  299. return buttonBorder;
  300. }
  301. private static Border textBorder;
  302. /**
  303. * Returns a border instance for a text component
  304. * @since 1.3
  305. */
  306. public static Border getTextBorder() {
  307. if (textBorder == null) {
  308. textBorder = new BorderUIResource.CompoundBorderUIResource(
  309. new MetalBorders.Flush3DBorder(),
  310. new BasicBorders.MarginBorder());
  311. }
  312. return textBorder;
  313. }
  314. private static Border textFieldBorder;
  315. /**
  316. * Returns a border instance for a JTextField
  317. * @since 1.3
  318. */
  319. public static Border getTextFieldBorder() {
  320. if (textFieldBorder == null) {
  321. textFieldBorder = new BorderUIResource.CompoundBorderUIResource(
  322. new MetalBorders.TextFieldBorder(),
  323. new BasicBorders.MarginBorder());
  324. }
  325. return textFieldBorder;
  326. }
  327. public static class TextFieldBorder extends Flush3DBorder {
  328. public void paintBorder(Component c, Graphics g, int x, int y,
  329. int w, int h) {
  330. if (!(c instanceof JTextComponent)) {
  331. // special case for non-text components (bug ID 4144840)
  332. if (c.isEnabled()) {
  333. MetalUtils.drawFlush3DBorder(g, x, y, w, h);
  334. } else {
  335. MetalUtils.drawDisabledBorder(g, x, y, w, h);
  336. }
  337. return;
  338. }
  339. if (c.isEnabled() && ((JTextComponent)c).isEditable()) {
  340. MetalUtils.drawFlush3DBorder(g, x, y, w, h);
  341. } else {
  342. MetalUtils.drawDisabledBorder(g, x, y, w, h);
  343. }
  344. }
  345. }
  346. public static class ScrollPaneBorder extends AbstractBorder implements UIResource {
  347. private static final Insets insets = new Insets(1, 1, 2, 2);
  348. public void paintBorder(Component c, Graphics g, int x, int y,
  349. int w, int h) {
  350. JScrollPane scroll = (JScrollPane)c;
  351. JComponent colHeader = scroll.getColumnHeader();
  352. int colHeaderHeight = 0;
  353. if (colHeader != null)
  354. colHeaderHeight = colHeader.getHeight();
  355. JComponent rowHeader = scroll.getRowHeader();
  356. int rowHeaderWidth = 0;
  357. if (rowHeader != null)
  358. rowHeaderWidth = rowHeader.getWidth();
  359. g.translate( x, y);
  360. g.setColor( MetalLookAndFeel.getControlDarkShadow() );
  361. g.drawRect( 0, 0, w-2, h-2 );
  362. g.setColor( MetalLookAndFeel.getControlHighlight() );
  363. g.drawLine( w-1, 1, w-1, h-1);
  364. g.drawLine( 1, h-1, w-1, h-1);
  365. g.setColor( MetalLookAndFeel.getControl() );
  366. g.drawLine( w-2, 2+colHeaderHeight, w-2, 2+colHeaderHeight );
  367. g.drawLine( 1+rowHeaderWidth, h-2, 1+rowHeaderWidth, h-2 );
  368. g.translate( -x, -y);
  369. }
  370. public Insets getBorderInsets(Component c) {
  371. return insets;
  372. }
  373. }
  374. private static Border toggleButtonBorder;
  375. /**
  376. * Returns a border instance for a JToggleButton
  377. * @since 1.3
  378. */
  379. public static Border getToggleButtonBorder() {
  380. if (toggleButtonBorder == null) {
  381. toggleButtonBorder = new BorderUIResource.CompoundBorderUIResource(
  382. new MetalBorders.ToggleButtonBorder(),
  383. new BasicBorders.MarginBorder());
  384. }
  385. return toggleButtonBorder;
  386. }
  387. public static class ToggleButtonBorder extends ButtonBorder {
  388. public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
  389. JToggleButton button = (JToggleButton)c;
  390. ButtonModel model = button.getModel();
  391. if (! c.isEnabled() ) {
  392. MetalUtils.drawDisabledBorder( g, x, y, w-1, h-1 );
  393. } else {
  394. if ( model.isPressed() && model.isArmed() ) {
  395. MetalUtils.drawPressed3DBorder( g, x, y, w, h );
  396. } else if ( model.isSelected() ) {
  397. MetalUtils.drawDark3DBorder( g, x, y, w, h );
  398. } else {
  399. MetalUtils.drawFlush3DBorder( g, x, y, w, h );
  400. }
  401. }
  402. }
  403. }
  404. /**
  405. * Border for a Table Header
  406. * @since 1.3
  407. */
  408. public static class TableHeaderBorder extends javax.swing.border.AbstractBorder {
  409. protected Insets editorBorderInsets = new Insets( 2, 2, 2, 0 );
  410. public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
  411. g.translate( x, y );
  412. g.setColor( MetalLookAndFeel.getControlDarkShadow() );
  413. g.drawLine( w-1, 0, w-1, h-1 );
  414. g.drawLine( 1, h-1, w-1, h-1 );
  415. g.setColor( MetalLookAndFeel.getControlHighlight() );
  416. g.drawLine( 0, 0, w-2, 0 );
  417. g.drawLine( 0, 0, 0, h-2 );
  418. g.translate( -x, -y );
  419. }
  420. public Insets getBorderInsets( Component c ) {
  421. return editorBorderInsets;
  422. }
  423. }
  424. /**
  425. * Returns a border instance for a Desktop Icon
  426. * @since 1.3
  427. */
  428. public static Border getDesktopIconBorder() {
  429. return new BorderUIResource.CompoundBorderUIResource(
  430. new LineBorder(MetalLookAndFeel.getControlDarkShadow(), 1),
  431. new MatteBorder (2,2,1,2, MetalLookAndFeel.getControl()));
  432. }
  433. }