1. /*
  2. * @(#)MotifDesktopPaneUI.java 1.25 03/12/19
  3. *
  4. * Copyright 2004 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 java.awt.Rectangle;
  10. import java.awt.Dimension;
  11. import java.awt.Insets;
  12. import java.awt.Color;
  13. import java.awt.Graphics;
  14. import java.awt.Component;
  15. import java.awt.Point;
  16. import javax.swing.plaf.*;
  17. import java.io.Serializable;
  18. /**
  19. * <p>
  20. * <strong>Warning:</strong>
  21. * Serialized objects of this class will not be compatible with
  22. * future Swing releases. The current serialization support is appropriate
  23. * for short term storage or RMI between applications running the same
  24. * version of Swing. A future release of Swing will provide support for
  25. * long term persistence.
  26. *
  27. * @version 1.25 12/19/03
  28. * @author David Kloba
  29. */
  30. public class MotifDesktopPaneUI extends javax.swing.plaf.basic.BasicDesktopPaneUI
  31. {
  32. /// DesktopPaneUI methods
  33. public static ComponentUI createUI(JComponent d) {
  34. return new MotifDesktopPaneUI();
  35. }
  36. public MotifDesktopPaneUI() {
  37. }
  38. protected void installDesktopManager() {
  39. desktopManager = desktop.getDesktopManager();
  40. if(desktopManager == null) {
  41. desktopManager = new MotifDesktopManager();
  42. desktop.setDesktopManager(desktopManager);
  43. ((MotifDesktopManager)desktopManager).adjustIcons(desktop);
  44. }
  45. }
  46. public Insets getInsets(JComponent c) {return new Insets(0,0,0,0);}
  47. ////////////////////////////////////////////////////////////////////////////////////
  48. /// DragPane class
  49. ////////////////////////////////////////////////////////////////////////////////////
  50. private class DragPane extends JComponent {
  51. public void paint(Graphics g) {
  52. g.setColor(Color.darkGray);
  53. g.drawRect(0, 0, getWidth()-1, getHeight()-1);
  54. }
  55. };
  56. ////////////////////////////////////////////////////////////////////////////////////
  57. /// MotifDesktopManager class
  58. ////////////////////////////////////////////////////////////////////////////////////
  59. private class MotifDesktopManager extends DefaultDesktopManager implements Serializable, UIResource {
  60. JComponent dragPane;
  61. boolean usingDragPane = false;
  62. private transient JLayeredPane layeredPaneForDragPane;
  63. int iconWidth, iconHeight;
  64. // PENDING(klobad) this should be optimized
  65. public void setBoundsForFrame(JComponent f, int newX, int newY,
  66. int newWidth, int newHeight) {
  67. if(!usingDragPane) {
  68. boolean didResize;
  69. didResize = (f.getWidth() != newWidth || f.getHeight() != newHeight);
  70. Rectangle r = f.getBounds();
  71. f.setBounds(newX, newY, newWidth, newHeight);
  72. SwingUtilities.computeUnion(newX, newY, newWidth, newHeight, r);
  73. f.getParent().repaint(r.x, r.y, r.width, r.height);
  74. if(didResize) {
  75. f.validate();
  76. }
  77. } else {
  78. Rectangle r = dragPane.getBounds();
  79. dragPane.setBounds(newX, newY, newWidth, newHeight);
  80. SwingUtilities.computeUnion(newX, newY, newWidth, newHeight, r);
  81. dragPane.getParent().repaint(r.x, r.y, r.width, r.height);
  82. }
  83. }
  84. public void beginDraggingFrame(JComponent f) {
  85. usingDragPane = false;
  86. if(f.getParent() instanceof JLayeredPane) {
  87. if(dragPane == null)
  88. dragPane = new DragPane();
  89. layeredPaneForDragPane = (JLayeredPane)f.getParent();
  90. layeredPaneForDragPane.setLayer(dragPane, Integer.MAX_VALUE);
  91. dragPane.setBounds(f.getX(), f.getY(), f.getWidth(), f.getHeight());
  92. layeredPaneForDragPane.add(dragPane);
  93. usingDragPane = true;
  94. }
  95. }
  96. public void dragFrame(JComponent f, int newX, int newY) {
  97. setBoundsForFrame(f, newX, newY, f.getWidth(), f.getHeight());
  98. }
  99. public void endDraggingFrame(JComponent f) {
  100. if(usingDragPane) {
  101. layeredPaneForDragPane.remove(dragPane);
  102. usingDragPane = false;
  103. if (f instanceof JInternalFrame) {
  104. setBoundsForFrame(f, dragPane.getX(), dragPane.getY(),
  105. dragPane.getWidth(), dragPane.getHeight());
  106. } else if (f instanceof JInternalFrame.JDesktopIcon) {
  107. adjustBoundsForIcon((JInternalFrame.JDesktopIcon)f,
  108. dragPane.getX(), dragPane.getY());
  109. }
  110. }
  111. }
  112. public void beginResizingFrame(JComponent f, int direction) {
  113. usingDragPane = false;
  114. if(f.getParent() instanceof JLayeredPane) {
  115. if(dragPane == null)
  116. dragPane = new DragPane();
  117. JLayeredPane p = (JLayeredPane)f.getParent();
  118. p.setLayer(dragPane, Integer.MAX_VALUE);
  119. dragPane.setBounds(f.getX(), f.getY(),
  120. f.getWidth(), f.getHeight());
  121. p.add(dragPane);
  122. usingDragPane = true;
  123. }
  124. }
  125. public void resizeFrame(JComponent f, int newX, int newY,
  126. int newWidth, int newHeight) {
  127. setBoundsForFrame(f, newX, newY, newWidth, newHeight);
  128. }
  129. public void endResizingFrame(JComponent f) {
  130. if(usingDragPane) {
  131. JLayeredPane p = (JLayeredPane)f.getParent();
  132. p.remove(dragPane);
  133. usingDragPane = false;
  134. setBoundsForFrame(f, dragPane.getX(), dragPane.getY(),
  135. dragPane.getWidth(), dragPane.getHeight());
  136. }
  137. }
  138. public void iconifyFrame(JInternalFrame f) {
  139. JInternalFrame.JDesktopIcon icon = f.getDesktopIcon();
  140. Point p = icon.getLocation();
  141. adjustBoundsForIcon(icon, p.x, p.y);
  142. super.iconifyFrame(f);
  143. }
  144. /**
  145. * Change positions of icons in the desktop pane so that
  146. * they do not overlap
  147. */
  148. protected void adjustIcons(JDesktopPane desktop) {
  149. // We need to know Motif icon size
  150. JInternalFrame.JDesktopIcon icon = new JInternalFrame.JDesktopIcon(
  151. new JInternalFrame());
  152. Dimension iconSize = icon.getPreferredSize();
  153. iconWidth = iconSize.width;
  154. iconHeight = iconSize.height;
  155. JInternalFrame[] frames = desktop.getAllFrames();
  156. for (int i=0; i<frames.length; i++) {
  157. icon = frames[i].getDesktopIcon();
  158. Point ip = icon.getLocation();
  159. adjustBoundsForIcon(icon, ip.x, ip.y);
  160. }
  161. }
  162. /**
  163. * Change positions of icon so that it doesn't overlap
  164. * other icons.
  165. */
  166. protected void adjustBoundsForIcon(JInternalFrame.JDesktopIcon icon,
  167. int x, int y) {
  168. JDesktopPane c = icon.getDesktopPane();
  169. int maxy = c.getHeight();
  170. int w = iconWidth;
  171. int h = iconHeight;
  172. c.repaint(x, y, w, h);
  173. x = x < 0 ? 0 : x;
  174. y = y < 0 ? 0 : y;
  175. /* Fix for disappearing icons. If the y value is maxy then this
  176. * algorithm would place the icon in a non-displayed cell. Never
  177. * to be ssen again.*/
  178. y = y >= maxy ? (maxy - 1) : y;
  179. /* Compute the offset for the cell we are trying to go in. */
  180. int lx = (x / w) * w;
  181. int ygap = maxy % h;
  182. int ly = ((y-ygap) / h) * h + ygap;
  183. /* How far are we into the cell we dropped the icon in. */
  184. int dx = x - lx;
  185. int dy = y - ly;
  186. /* Set coordinates for the icon. */
  187. x = dx < w2 ? lx: lx + w;
  188. y = dy < h2 ? ly: ((ly + h) < maxy ? ly + h: ly);
  189. while (getIconAt(c, icon, x, y) != null) {
  190. x += w;
  191. }
  192. /* Cancel the move if the x value was moved off screen. */
  193. if (x > c.getWidth()) {
  194. return;
  195. }
  196. if (icon.getParent() != null) {
  197. setBoundsForFrame(icon, x, y, w, h);
  198. } else {
  199. icon.setLocation(x, y);
  200. }
  201. }
  202. protected JInternalFrame.JDesktopIcon getIconAt(JDesktopPane desktop,
  203. JInternalFrame.JDesktopIcon icon, int x, int y) {
  204. JInternalFrame.JDesktopIcon currentIcon = null;
  205. Component[] components = desktop.getComponents();
  206. for (int i=0; i<components.length; i++) {
  207. Component comp = components[i];
  208. if (comp instanceof JInternalFrame.JDesktopIcon &&
  209. comp != icon) {
  210. Point p = comp.getLocation();
  211. if (p.x == x && p.y == y) {
  212. return (JInternalFrame.JDesktopIcon)comp;
  213. }
  214. }
  215. }
  216. return null;
  217. }
  218. }; /// END of MotifDesktopManager
  219. }