1. /*
  2. * @(#)MotifBorders.java 1.26 01/11/29
  3. *
  4. * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.java.swing.plaf.motif;
  8. import javax.swing.*;
  9. import javax.swing.border.*;
  10. import javax.swing.plaf.*;
  11. import java.awt.Component;
  12. import java.awt.Insets;
  13. import java.awt.Dimension;
  14. import java.awt.Rectangle;
  15. import java.awt.Color;
  16. import java.awt.Graphics;
  17. import java.io.Serializable;
  18. /**
  19. * Factory object that can vend Icons appropriate for the basic L & F.
  20. * <p>
  21. * <strong>Warning:</strong>
  22. * Serialized objects of this class will not be compatible with
  23. * future Swing releases. The current serialization support is appropriate
  24. * for short term storage or RMI between applications running the same
  25. * version of Swing. A future release of Swing will provide support for
  26. * long term persistence.
  27. *
  28. * @version 1.26 11/29/01
  29. * @author Amy Fowler
  30. */
  31. public class MotifBorders {
  32. public static class BevelBorder extends AbstractBorder implements UIResource {
  33. private Color darkShadow = UIManager.getColor("controlShadow");
  34. private Color lightShadow = UIManager.getColor("controlLtHighlight");
  35. private boolean isRaised;
  36. public BevelBorder(boolean isRaised, Color darkShadow, Color lightShadow) {
  37. this.isRaised = isRaised;
  38. this.darkShadow = darkShadow;
  39. this.lightShadow = lightShadow;
  40. }
  41. public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
  42. g.setColor((isRaised) ? lightShadow : darkShadow);
  43. g.drawLine(x, y, x+w-1, y); // top
  44. g.drawLine(x, y+h-1, x, y+1); // left
  45. g.setColor((isRaised) ? darkShadow : lightShadow);
  46. g.drawLine(x+1, y+h-1, x+w-1, y+h-1); // bottom
  47. g.drawLine(x+w-1, y+h-1, x+w-1, y+1); // right
  48. }
  49. public Insets getBorderInsets(Component c) {
  50. return new Insets(1, 1, 1, 1);
  51. }
  52. public boolean isOpaque(Component c) {
  53. return true;
  54. }
  55. }
  56. public static class FocusBorder extends AbstractBorder implements UIResource {
  57. private Color focus;
  58. private Color control;
  59. public FocusBorder(Color control, Color focus) {
  60. this.control = control;
  61. this.focus = focus;
  62. }
  63. public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
  64. if (((JComponent)c).hasFocus()) {
  65. g.setColor(focus);
  66. g.drawRect(x, y, w-1, h-1);
  67. } else {
  68. g.setColor(control);
  69. g.drawRect(x, y, w-1, h-1);
  70. }
  71. }
  72. public Insets getBorderInsets(Component c) {
  73. return new Insets(1,1,1,1);
  74. }
  75. final static Insets insets = new Insets(1, 1, 1, 1);
  76. }
  77. public static class ButtonBorder extends AbstractBorder implements UIResource {
  78. protected Color focus = UIManager.getColor("activeCaptionBorder");
  79. protected Color shadow = UIManager.getColor("controlShadow");
  80. protected Color highlight = UIManager.getColor("controlHighlight");
  81. protected Color darkShadow;
  82. public ButtonBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
  83. this.shadow = shadow;
  84. this.highlight = highlight;
  85. this.darkShadow = darkShadow;
  86. this.focus = focus;
  87. }
  88. public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
  89. boolean isPressed = false;
  90. boolean hasFocus = false;
  91. boolean canBeDefault = false;
  92. boolean isDefault = false;
  93. if (c instanceof AbstractButton) {
  94. AbstractButton b = (AbstractButton)c;
  95. ButtonModel model = b.getModel();
  96. isPressed = (model.isArmed() && model.isPressed());
  97. hasFocus = (model.isArmed() && isPressed) ||
  98. (b.isFocusPainted() && b.hasFocus());
  99. if (b instanceof JButton) {
  100. canBeDefault = ((JButton)b).isDefaultCapable();
  101. isDefault = ((JButton)b).isDefaultButton();
  102. }
  103. }
  104. int bx1 = x+1;
  105. int by1 = y+1;
  106. int bx2 = x+w-2;
  107. int by2 = y+h-2;
  108. if (canBeDefault) {
  109. if (isDefault) {
  110. g.setColor(shadow);
  111. g.drawLine(x+3, y+3, x+3, y+h-4);
  112. g.drawLine(x+3, y+3, x+w-4, y+3);
  113. g.setColor(highlight);
  114. g.drawLine(x+4, y+h-4, x+w-4, y+h-4);
  115. g.drawLine(x+w-4, y+3, x+w-4, y+h-4);
  116. }
  117. bx1 +=6;
  118. by1 += 6;
  119. bx2 -= 6;
  120. by2 -= 6;
  121. }
  122. if (hasFocus) {
  123. g.setColor(focus);
  124. if (isDefault) {
  125. g.drawRect(x, y, w-1, h-1);
  126. } else {
  127. g.drawRect(bx1-1, by1-1, bx2-bx1+2, by2-by1+2);
  128. }
  129. }
  130. g.setColor(isPressed? shadow : highlight);
  131. g.drawLine(bx1, by1, bx2, by1);
  132. g.drawLine(bx1, by1, bx1, by2);
  133. g.setColor(isPressed? highlight : shadow);
  134. g.drawLine(bx2, by1+1, bx2, by2);
  135. g.drawLine(bx1+1, by2, bx2, by2);
  136. }
  137. public Insets getBorderInsets(Component c) {
  138. if (c instanceof JButton) {
  139. JButton b = (JButton)c;
  140. return (b.isDefaultCapable()? new Insets(8, 8, 8, 8) :
  141. new Insets(2, 2, 2, 2));
  142. }
  143. return new Insets(2, 2, 2, 2);
  144. }
  145. }
  146. public static class ToggleButtonBorder extends ButtonBorder {
  147. public ToggleButtonBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
  148. super(shadow, highlight, darkShadow, focus);
  149. }
  150. public void paintBorder(Component c, Graphics g, int x, int y,
  151. int width, int height) {
  152. if (c instanceof AbstractButton) {
  153. AbstractButton b = (AbstractButton)c;
  154. ButtonModel model = b.getModel();
  155. if (model.isArmed() && model.isPressed() || model.isSelected()) {
  156. drawBezel(g, x, y, width, height,
  157. (model.isPressed() || model.isSelected()),
  158. b.isFocusPainted() && b.hasFocus(), shadow, highlight, darkShadow, focus);
  159. } else {
  160. drawBezel(g, x, y, width, height,
  161. false, b.isFocusPainted() && b.hasFocus(),
  162. shadow, highlight, darkShadow, focus);
  163. }
  164. } else {
  165. drawBezel(g, x, y, width, height, false, false,
  166. shadow, highlight, darkShadow, focus);
  167. }
  168. }
  169. public Insets getBorderInsets(Component c) {
  170. return new Insets(2, 2, 3, 3);
  171. }
  172. }
  173. public static class MenuBarBorder extends ButtonBorder {
  174. public MenuBarBorder(Color shadow, Color highlight, Color darkShadow, Color focus) {
  175. super(shadow, highlight, darkShadow, focus);
  176. }
  177. public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
  178. JMenuBar menuBar = (JMenuBar)c;
  179. if (menuBar.isBorderPainted() == true) {
  180. // this draws the MenuBar border
  181. Dimension size = menuBar.getSize();
  182. drawBezel(g,x,y,size.width,size.height,false,false,
  183. shadow, highlight, darkShadow, focus);
  184. }
  185. }
  186. public Insets getBorderInsets(Component c) {
  187. return new Insets(6,6,6,6);
  188. }
  189. }
  190. public static class FrameBorder extends AbstractBorder implements UIResource {
  191. JComponent jcomp;
  192. Color frameHighlight;
  193. Color frameColor;
  194. Color frameShadow;
  195. // The width of the border
  196. public final static int BORDER_SIZE = 5;
  197. /** Constructs an FrameBorder for the JComponent <b>comp</b>.
  198. */
  199. public FrameBorder(JComponent comp) {
  200. jcomp = comp;
  201. }
  202. /** Sets the FrameBorder's JComponent.
  203. */
  204. public void setComponent(JComponent comp) {
  205. jcomp = comp;
  206. }
  207. /** Returns the FrameBorder's JComponent.
  208. * @see #setComponent
  209. */
  210. public JComponent component() {
  211. return jcomp;
  212. }
  213. protected Color getFrameHighlight() {
  214. return frameHighlight;
  215. }
  216. protected Color getFrameColor() {
  217. return frameColor;
  218. }
  219. protected Color getFrameShadow() {
  220. return frameShadow;
  221. }
  222. static Insets insets = new Insets(BORDER_SIZE, BORDER_SIZE,
  223. BORDER_SIZE, BORDER_SIZE);
  224. public Insets getBorderInsets(Component c) {
  225. return insets;
  226. }
  227. /** Draws the FrameBorder's top border.
  228. */
  229. protected boolean drawTopBorder(Component c, Graphics g,
  230. int x, int y, int width, int height) {
  231. Rectangle titleBarRect = new Rectangle(x, y, width, BORDER_SIZE);
  232. if (!g.getClipBounds().intersects(titleBarRect)) {
  233. return false;
  234. }
  235. int maxX = width - 1;
  236. int maxY = BORDER_SIZE - 1;
  237. // Draw frame
  238. g.setColor(frameColor);
  239. g.drawLine(x, y + 2, maxX - 2, y + 2);
  240. g.drawLine(x, y + 3, maxX - 2, y + 3);
  241. g.drawLine(x, y + 4, maxX - 2, y + 4);
  242. // Draw highlights
  243. g.setColor(frameHighlight);
  244. g.drawLine(x, y, maxX, y);
  245. g.drawLine(x, y + 1, maxX, y + 1);
  246. g.drawLine(x, y + 2, x, y + 4);
  247. g.drawLine(x + 1, y + 2, x + 1, y + 4);
  248. // Draw shadows
  249. g.setColor(frameShadow);
  250. g.drawLine(x + 4, y + 4, maxX - 4, y + 4);
  251. g.drawLine(maxX, y + 1, maxX, maxY);
  252. g.drawLine(maxX - 1, y + 2, maxX - 1, maxY);
  253. return true;
  254. }
  255. /** Draws the FrameBorder's left border.
  256. */
  257. protected boolean drawLeftBorder(Component c, Graphics g, int x, int y,
  258. int width, int height) {
  259. Rectangle borderRect =
  260. new Rectangle(0, 0, getBorderInsets(c).left, height);
  261. if (!g.getClipBounds().intersects(borderRect)) {
  262. return false;
  263. }
  264. int startY = BORDER_SIZE;
  265. g.setColor(frameHighlight);
  266. g.drawLine(x, startY, x, height - 1);
  267. g.drawLine(x + 1, startY, x + 1, height - 2);
  268. g.setColor(frameColor);
  269. g.fillRect(x + 2, startY, x + 2, height - 3);
  270. g.setColor(frameShadow);
  271. g.drawLine(x + 4, startY, x + 4, height - 5);
  272. return true;
  273. }
  274. /** Draws the FrameBorder's right border.
  275. */
  276. protected boolean drawRightBorder(Component c, Graphics g, int x, int y,
  277. int width, int height) {
  278. Rectangle borderRect = new Rectangle(
  279. width - getBorderInsets(c).right, 0,
  280. getBorderInsets(c).right, height);
  281. if (!g.getClipBounds().intersects(borderRect)) {
  282. return false;
  283. }
  284. int startX = width - getBorderInsets(c).right;
  285. int startY = BORDER_SIZE;
  286. g.setColor(frameColor);
  287. g.fillRect(startX + 1, startY, 2, height - 1);
  288. g.setColor(frameShadow);
  289. g.fillRect(startX + 3, startY, 2, height - 1);
  290. g.setColor(frameHighlight);
  291. g.drawLine(startX, startY, startX, height - 1);
  292. return true;
  293. }
  294. /** Draws the FrameBorder's bottom border.
  295. */
  296. protected boolean drawBottomBorder(Component c, Graphics g, int x, int y,
  297. int width, int height) {
  298. Rectangle borderRect;
  299. int marginHeight, startY;
  300. borderRect = new Rectangle(0, height - getBorderInsets(c).bottom,
  301. width, getBorderInsets(c).bottom);
  302. if (!g.getClipBounds().intersects(borderRect)) {
  303. return false;
  304. }
  305. startY = height - getBorderInsets(c).bottom;
  306. g.setColor(frameShadow);
  307. g.drawLine(x + 1, height - 1, width - 1, height - 1);
  308. g.drawLine(x + 2, height - 2, width - 2, height - 2);
  309. g.setColor(frameColor);
  310. g.fillRect(x + 2, startY + 1, width - 4, 2);
  311. g.setColor(frameHighlight);
  312. g.drawLine(x + 5, startY, width - 5, startY);
  313. return true;
  314. }
  315. // Returns true if the associated component has focus.
  316. protected boolean isActiveFrame() {
  317. return jcomp.hasFocus();
  318. }
  319. /** Draws the FrameBorder in the given Rect. Calls
  320. * <b>drawTitleBar</b>, <b>drawLeftBorder</b>, <b>drawRightBorder</b> and
  321. * <b>drawBottomBorder</b>.
  322. */
  323. public void paintBorder(Component c, Graphics g,
  324. int x, int y, int width, int height) {
  325. if (isActiveFrame()) {
  326. frameColor = UIManager.getColor("activeCaptionBorder");
  327. } else {
  328. frameColor = UIManager.getColor("inactiveCaptionBorder");
  329. }
  330. frameHighlight = frameColor.brighter();
  331. frameShadow = frameColor.darker().darker();
  332. drawTopBorder(c, g, x, y, width, height);
  333. drawLeftBorder(c, g, x, y, width, height);
  334. drawRightBorder(c, g, x, y, width, height);
  335. drawBottomBorder(c, g, x, y, width, height);
  336. }
  337. }
  338. public static class InternalFrameBorder extends FrameBorder {
  339. JInternalFrame frame;
  340. // The size of the bounding box for Motif frame corners.
  341. public final static int CORNER_SIZE = 24;
  342. /** Constructs an InternalFrameBorder for the InternalFrame
  343. * <b>aFrame</b>.
  344. */
  345. public InternalFrameBorder(JInternalFrame aFrame) {
  346. FrameBorder.super(aFrame);
  347. frame = aFrame;
  348. }
  349. /** Sets the InternalFrameBorder's InternalFrame.
  350. */
  351. public void setFrame(JInternalFrame aFrame) {
  352. frame = aFrame;
  353. }
  354. /** Returns the InternalFrameBorder's InternalFrame.
  355. * @see #setFrame
  356. */
  357. public JInternalFrame frame() {
  358. return frame;
  359. }
  360. /** Returns the width of the InternalFrameBorder's resize controls,
  361. * appearing along the InternalFrameBorder's bottom border. Clicking
  362. * and dragging within these controls lets the user change both the
  363. * InternalFrame's width and height, while dragging between the controls
  364. * constrains resizing to just the vertical dimension. Override this
  365. * method if you implement your own bottom border painting and use a
  366. * resize control with a different size.
  367. */
  368. public int resizePartWidth() {
  369. if (!frame.isResizable()) {
  370. return 0;
  371. }
  372. return FrameBorder.BORDER_SIZE;
  373. }
  374. /** Draws the InternalFrameBorder's top border.
  375. */
  376. protected boolean drawTopBorder(Component c, Graphics g,
  377. int x, int y, int width, int height) {
  378. if (super.drawTopBorder(c, g, x, y, width, height) &&
  379. frame.isResizable()) {
  380. g.setColor(getFrameShadow());
  381. g.drawLine(CORNER_SIZE - 1, y + 1, CORNER_SIZE - 1, y + 4);
  382. g.drawLine(width - CORNER_SIZE - 1, y + 1,
  383. width - CORNER_SIZE - 1, y + 4);
  384. g.setColor(getFrameHighlight());
  385. g.drawLine(CORNER_SIZE, y, CORNER_SIZE, y + 4);
  386. g.drawLine(width - CORNER_SIZE, y, width - CORNER_SIZE, y + 4);
  387. return true;
  388. }
  389. return false;
  390. }
  391. /** Draws the InternalFrameBorder's left border.
  392. */
  393. protected boolean drawLeftBorder(Component c, Graphics g, int x, int y,
  394. int width, int height) {
  395. if (super.drawLeftBorder(c, g, x, y, width, height) &&
  396. frame.isResizable()) {
  397. g.setColor(getFrameHighlight());
  398. int topY = y + CORNER_SIZE;
  399. g.drawLine(x, topY, x + 4, topY);
  400. int bottomY = height - CORNER_SIZE;
  401. g.drawLine(x + 1, bottomY, x + 5, bottomY);
  402. g.setColor(getFrameShadow());
  403. g.drawLine(x + 1, topY - 1, x + 5, topY - 1);
  404. g.drawLine(x + 1, bottomY - 1, x + 5, bottomY - 1);
  405. return true;
  406. }
  407. return false;
  408. }
  409. /** Draws the InternalFrameBorder's right border.
  410. */
  411. protected boolean drawRightBorder(Component c, Graphics g, int x, int y,
  412. int width, int height) {
  413. if (super.drawRightBorder(c, g, x, y, width, height) &&
  414. frame.isResizable()) {
  415. int startX = width - getBorderInsets(c).right;
  416. g.setColor(getFrameHighlight());
  417. int topY = y + CORNER_SIZE;
  418. g.drawLine(startX, topY, width - 2, topY);
  419. int bottomY = height - CORNER_SIZE;
  420. g.drawLine(startX + 1, bottomY, startX + 3, bottomY);
  421. g.setColor(getFrameShadow());
  422. g.drawLine(startX + 1, topY - 1, width - 2, topY - 1);
  423. g.drawLine(startX + 1, bottomY - 1, startX + 3, bottomY - 1);
  424. return true;
  425. }
  426. return false;
  427. }
  428. /** Draws the InternalFrameBorder's bottom border.
  429. */
  430. protected boolean drawBottomBorder(Component c, Graphics g, int x, int y,
  431. int width, int height) {
  432. if (super.drawBottomBorder(c, g, x, y, width, height) &&
  433. frame.isResizable()) {
  434. int startY = height - getBorderInsets(c).bottom;
  435. g.setColor(getFrameShadow());
  436. g.drawLine(CORNER_SIZE - 1, startY + 1,
  437. CORNER_SIZE - 1, height - 1);
  438. g.drawLine(width - CORNER_SIZE, startY + 1,
  439. width - CORNER_SIZE, height - 1);
  440. g.setColor(getFrameHighlight());
  441. g.drawLine(CORNER_SIZE, startY, CORNER_SIZE, height - 2);
  442. g.drawLine(width - CORNER_SIZE + 1, startY,
  443. width - CORNER_SIZE + 1, height - 2);
  444. return true;
  445. }
  446. return false;
  447. }
  448. // Returns true if the associated internal frame has focus.
  449. protected boolean isActiveFrame() {
  450. return frame.isSelected();
  451. }
  452. }
  453. public static void drawBezel(Graphics g, int x, int y, int w, int h,
  454. boolean isPressed, boolean hasFocus,
  455. Color shadow, Color highlight,
  456. Color darkShadow, Color focus) {
  457. Color oldColor = g.getColor();
  458. g.translate(x, y);
  459. if (isPressed) {
  460. if (hasFocus){
  461. g.setColor(focus);
  462. g.drawRect(0, 0, w-1, h-1);
  463. }
  464. g.setColor(shadow); // inner border
  465. g.drawRect(1, 1, w-3, h-3);
  466. g.setColor(highlight); // inner 3D border
  467. g.drawLine(2, h-3, w-3, h-3);
  468. g.drawLine(w-3, 2, w-3, h-4);
  469. } else {
  470. if (hasFocus) {
  471. g.setColor(focus);
  472. g.drawRect(0, 0, w-1, h-1);
  473. g.setColor(highlight); // inner 3D border
  474. g.drawLine(1, 1, 1, h-3);
  475. g.drawLine(2, 1, w-4, 1);
  476. g.setColor(shadow);
  477. g.drawLine(2, h-3, w-3, h-3);
  478. g.drawLine(w-3, 1, w-3, h-4);
  479. g.setColor(darkShadow); // black drop shadow __|
  480. g.drawLine(1, h-2, w-2, h-2);
  481. g.drawLine(w-2, h-2, w-2, 1);
  482. } else {
  483. g.setColor(highlight); // inner 3D border
  484. g.drawLine(1,1,1,h-3);
  485. g.drawLine(2,1,w-4,1);
  486. g.setColor(shadow);
  487. g.drawLine(2,h-3,w-3,h-3);
  488. g.drawLine(w-3,1,w-3,h-4);
  489. g.setColor(darkShadow); // black drop shadow __|
  490. g.drawLine(1,h-2,w-2,h-2);
  491. g.drawLine(w-2,h-2,w-2,0);
  492. }
  493. g.translate(-x, -y);
  494. }
  495. g.setColor(oldColor);
  496. }
  497. }