1. /*
  2. * @(#)BasicInternalFrameUI.java 1.118 04/05/18
  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.basic;
  8. import java.awt.*;
  9. import java.awt.event.*;
  10. import java.awt.peer.LightweightPeer;
  11. import javax.swing.*;
  12. import javax.swing.border.*;
  13. import javax.swing.plaf.*;
  14. import javax.swing.event.*;
  15. import java.beans.*;
  16. import java.io.Serializable;
  17. import sun.swing.DefaultLookup;
  18. import sun.swing.UIAction;
  19. /**
  20. * A basic L&F implementation of JInternalFrame.
  21. *
  22. * @version 1.118 05/18/04
  23. * @author David Kloba
  24. * @author Rich Schiavi
  25. */
  26. public class BasicInternalFrameUI extends InternalFrameUI
  27. {
  28. protected JInternalFrame frame;
  29. private Handler handler;
  30. protected MouseInputAdapter borderListener;
  31. protected PropertyChangeListener propertyChangeListener;
  32. protected LayoutManager internalFrameLayout;
  33. protected ComponentListener componentListener;
  34. protected MouseInputListener glassPaneDispatcher;
  35. private InternalFrameListener internalFrameListener;
  36. protected JComponent northPane;
  37. protected JComponent southPane;
  38. protected JComponent westPane;
  39. protected JComponent eastPane;
  40. protected BasicInternalFrameTitlePane titlePane; // access needs this
  41. private static DesktopManager sharedDesktopManager;
  42. private boolean componentListenerAdded = false;
  43. private Rectangle parentBounds;
  44. private boolean dragging = false;
  45. /**
  46. * As of Java 2 platform v1.3 this previously undocumented field is no
  47. * longer used.
  48. * Key bindings are now defined by the LookAndFeel, please refer to
  49. * the key bindings specification for further details.
  50. *
  51. * @deprecated As of Java 2 platform v1.3.
  52. */
  53. @Deprecated
  54. protected KeyStroke openMenuKey;
  55. private boolean keyBindingRegistered = false;
  56. private boolean keyBindingActive = false;
  57. /////////////////////////////////////////////////////////////////////////////
  58. // ComponentUI Interface Implementation methods
  59. /////////////////////////////////////////////////////////////////////////////
  60. public static ComponentUI createUI(JComponent b) {
  61. return new BasicInternalFrameUI((JInternalFrame)b);
  62. }
  63. public BasicInternalFrameUI(JInternalFrame b) {
  64. }
  65. public void installUI(JComponent c) {
  66. frame = (JInternalFrame)c;
  67. installDefaults();
  68. installListeners();
  69. installComponents();
  70. installKeyboardActions();
  71. LookAndFeel.installProperty(frame, "opaque", Boolean.TRUE);
  72. }
  73. public void uninstallUI(JComponent c) {
  74. if(c != frame)
  75. throw new IllegalComponentStateException(
  76. this + " was asked to deinstall() "
  77. + c + " when it only knows about "
  78. + frame + ".");
  79. uninstallKeyboardActions();
  80. uninstallComponents();
  81. uninstallListeners();
  82. uninstallDefaults();
  83. frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  84. handler = null;
  85. frame = null;
  86. }
  87. protected void installDefaults(){
  88. Icon frameIcon = frame.getFrameIcon();
  89. if (frameIcon == null || frameIcon instanceof UIResource) {
  90. frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon"));
  91. }
  92. // Enable the content pane to inherit background color from its
  93. // parent by setting its background color to null.
  94. JComponent contentPane = (JComponent) frame.getContentPane();
  95. if (contentPane != null) {
  96. Color bg = contentPane.getBackground();
  97. if (bg instanceof UIResource)
  98. contentPane.setBackground(null);
  99. }
  100. frame.setLayout(internalFrameLayout = createLayoutManager());
  101. frame.setBackground(UIManager.getLookAndFeelDefaults().getColor("control"));
  102. LookAndFeel.installBorder(frame, "InternalFrame.border");
  103. }
  104. protected void installKeyboardActions(){
  105. createInternalFrameListener();
  106. if (internalFrameListener != null) {
  107. frame.addInternalFrameListener(internalFrameListener);
  108. }
  109. LazyActionMap.installLazyActionMap(frame, BasicInternalFrameUI.class,
  110. "InternalFrame.actionMap");
  111. }
  112. static void loadActionMap(LazyActionMap map) {
  113. map.put(new UIAction("showSystemMenu") {
  114. public void actionPerformed(ActionEvent evt) {
  115. JInternalFrame iFrame = (JInternalFrame)evt.getSource();
  116. if (iFrame.getUI() instanceof BasicInternalFrameUI) {
  117. JComponent comp = ((BasicInternalFrameUI)
  118. iFrame.getUI()).getNorthPane();
  119. if (comp instanceof BasicInternalFrameTitlePane) {
  120. ((BasicInternalFrameTitlePane)comp).
  121. showSystemMenu();
  122. }
  123. }
  124. }
  125. public boolean isEnabled(Object sender){
  126. if (sender instanceof JInternalFrame) {
  127. JInternalFrame iFrame = (JInternalFrame)sender;
  128. if (iFrame.getUI() instanceof BasicInternalFrameUI) {
  129. return ((BasicInternalFrameUI)iFrame.getUI()).
  130. isKeyBindingActive();
  131. }
  132. }
  133. return false;
  134. }
  135. });
  136. // Set the ActionMap's parent to the Auditory Feedback Action Map
  137. BasicLookAndFeel.installAudioActionMap(map);
  138. }
  139. protected void installComponents(){
  140. setNorthPane(createNorthPane(frame));
  141. setSouthPane(createSouthPane(frame));
  142. setEastPane(createEastPane(frame));
  143. setWestPane(createWestPane(frame));
  144. }
  145. /*
  146. * @since 1.3
  147. */
  148. protected void installListeners() {
  149. borderListener = createBorderListener(frame);
  150. propertyChangeListener = createPropertyChangeListener();
  151. frame.addPropertyChangeListener(propertyChangeListener);
  152. installMouseHandlers(frame);
  153. glassPaneDispatcher = createGlassPaneDispatcher();
  154. frame.getGlassPane().addMouseListener(glassPaneDispatcher);
  155. frame.getGlassPane().addMouseMotionListener(glassPaneDispatcher);
  156. componentListener = createComponentListener();
  157. if (frame.getParent() != null) {
  158. parentBounds = frame.getParent().getBounds();
  159. }
  160. if ((frame.getParent() != null) && !componentListenerAdded) {
  161. frame.getParent().addComponentListener(componentListener);
  162. componentListenerAdded = true;
  163. }
  164. }
  165. private Handler getHandler() {
  166. if (handler == null) {
  167. handler = new Handler();
  168. }
  169. return handler;
  170. }
  171. InputMap getInputMap(int condition) {
  172. if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
  173. return createInputMap(condition);
  174. }
  175. return null;
  176. }
  177. InputMap createInputMap(int condition) {
  178. if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
  179. Object[] bindings = (Object[])DefaultLookup.get(
  180. frame, this, "InternalFrame.windowBindings");
  181. if (bindings != null) {
  182. return LookAndFeel.makeComponentInputMap(frame, bindings);
  183. }
  184. }
  185. return null;
  186. }
  187. protected void uninstallDefaults() {
  188. Icon frameIcon = frame.getFrameIcon();
  189. if (frameIcon instanceof UIResource) {
  190. frame.setFrameIcon(null);
  191. }
  192. internalFrameLayout = null;
  193. frame.setLayout(null);
  194. LookAndFeel.uninstallBorder(frame);
  195. }
  196. protected void uninstallComponents(){
  197. setNorthPane(null);
  198. setSouthPane(null);
  199. setEastPane(null);
  200. setWestPane(null);
  201. if(titlePane != null) {
  202. titlePane.uninstallDefaults();
  203. }
  204. titlePane = null;
  205. }
  206. /*
  207. * @since 1.3
  208. */
  209. protected void uninstallListeners() {
  210. if ((frame.getParent() != null) && componentListenerAdded) {
  211. frame.getParent().removeComponentListener(componentListener);
  212. componentListenerAdded = false;
  213. }
  214. componentListener = null;
  215. frame.getGlassPane().removeMouseListener(glassPaneDispatcher);
  216. frame.getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
  217. glassPaneDispatcher = null;
  218. deinstallMouseHandlers(frame);
  219. frame.removePropertyChangeListener(propertyChangeListener);
  220. propertyChangeListener = null;
  221. borderListener = null;
  222. }
  223. protected void uninstallKeyboardActions(){
  224. if (internalFrameListener != null) {
  225. frame.removeInternalFrameListener(internalFrameListener);
  226. }
  227. internalFrameListener = null;
  228. SwingUtilities.replaceUIInputMap(frame, JComponent.
  229. WHEN_IN_FOCUSED_WINDOW, null);
  230. SwingUtilities.replaceUIActionMap(frame, null);
  231. }
  232. protected LayoutManager createLayoutManager(){
  233. return getHandler();
  234. }
  235. protected PropertyChangeListener createPropertyChangeListener(){
  236. return getHandler();
  237. }
  238. public Dimension getPreferredSize(JComponent x) {
  239. if((JComponent)frame == x)
  240. return frame.getLayout().preferredLayoutSize(x);
  241. return new Dimension(100, 100);
  242. }
  243. public Dimension getMinimumSize(JComponent x) {
  244. if((JComponent)frame == x) {
  245. return frame.getLayout().minimumLayoutSize(x);
  246. }
  247. return new Dimension(0, 0);
  248. }
  249. public Dimension getMaximumSize(JComponent x) {
  250. return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  251. }
  252. /**
  253. * Installs necessary mouse handlers on <code>newPane</code>
  254. * and adds it to the frame.
  255. * Reverse process for the <code>currentPane</code>.
  256. */
  257. protected void replacePane(JComponent currentPane, JComponent newPane) {
  258. if(currentPane != null) {
  259. deinstallMouseHandlers(currentPane);
  260. frame.remove(currentPane);
  261. }
  262. if(newPane != null) {
  263. frame.add(newPane);
  264. installMouseHandlers(newPane);
  265. }
  266. }
  267. protected void deinstallMouseHandlers(JComponent c) {
  268. c.removeMouseListener(borderListener);
  269. c.removeMouseMotionListener(borderListener);
  270. }
  271. protected void installMouseHandlers(JComponent c) {
  272. c.addMouseListener(borderListener);
  273. c.addMouseMotionListener(borderListener);
  274. }
  275. protected JComponent createNorthPane(JInternalFrame w) {
  276. titlePane = new BasicInternalFrameTitlePane(w);
  277. return titlePane;
  278. }
  279. protected JComponent createSouthPane(JInternalFrame w) {
  280. return null;
  281. }
  282. protected JComponent createWestPane(JInternalFrame w) {
  283. return null;
  284. }
  285. protected JComponent createEastPane(JInternalFrame w) {
  286. return null;
  287. }
  288. protected MouseInputAdapter createBorderListener(JInternalFrame w) {
  289. return new BorderListener();
  290. }
  291. protected void createInternalFrameListener(){
  292. internalFrameListener = getHandler();
  293. }
  294. protected final boolean isKeyBindingRegistered(){
  295. return keyBindingRegistered;
  296. }
  297. protected final void setKeyBindingRegistered(boolean b){
  298. keyBindingRegistered = b;
  299. }
  300. public final boolean isKeyBindingActive(){
  301. return keyBindingActive;
  302. }
  303. protected final void setKeyBindingActive(boolean b){
  304. keyBindingActive = b;
  305. }
  306. protected void setupMenuOpenKey(){
  307. // PENDING(hania): Why are these WHEN_IN_FOCUSED_WINDOWs? Shouldn't
  308. // they be WHEN_ANCESTOR_OF_FOCUSED_COMPONENT?
  309. // Also, no longer registering on the desktopicon, the previous
  310. // action did nothing.
  311. InputMap map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
  312. SwingUtilities.replaceUIInputMap(frame,
  313. JComponent.WHEN_IN_FOCUSED_WINDOW, map);
  314. //ActionMap actionMap = getActionMap();
  315. //SwingUtilities.replaceUIActionMap(frame, actionMap);
  316. }
  317. protected void setupMenuCloseKey(){
  318. }
  319. public JComponent getNorthPane() {
  320. return northPane;
  321. }
  322. public void setNorthPane(JComponent c) {
  323. if (northPane != null &&
  324. northPane instanceof BasicInternalFrameTitlePane) {
  325. ((BasicInternalFrameTitlePane)northPane).uninstallListeners();
  326. }
  327. replacePane(northPane, c);
  328. northPane = c;
  329. }
  330. public JComponent getSouthPane() {
  331. return southPane;
  332. }
  333. public void setSouthPane(JComponent c) {
  334. southPane = c;
  335. }
  336. public JComponent getWestPane() {
  337. return westPane;
  338. }
  339. public void setWestPane(JComponent c) {
  340. westPane = c;
  341. }
  342. public JComponent getEastPane() {
  343. return eastPane;
  344. }
  345. public void setEastPane(JComponent c) {
  346. eastPane = c;
  347. }
  348. public class InternalFramePropertyChangeListener implements
  349. PropertyChangeListener {
  350. // NOTE: This class exists only for backward compatability. All
  351. // its functionality has been moved into Handler. If you need to add
  352. // new functionality add it to the Handler, but make sure this
  353. // class calls into the Handler.
  354. /**
  355. * Detects changes in state from the JInternalFrame and handles
  356. * actions.
  357. */
  358. public void propertyChange(PropertyChangeEvent evt) {
  359. getHandler().propertyChange(evt);
  360. }
  361. }
  362. public class InternalFrameLayout implements LayoutManager {
  363. // NOTE: This class exists only for backward compatability. All
  364. // its functionality has been moved into Handler. If you need to add
  365. // new functionality add it to the Handler, but make sure this
  366. // class calls into the Handler.
  367. public void addLayoutComponent(String name, Component c) {
  368. getHandler().addLayoutComponent(name, c);
  369. }
  370. public void removeLayoutComponent(Component c) {
  371. getHandler().removeLayoutComponent(c);
  372. }
  373. public Dimension preferredLayoutSize(Container c) {
  374. return getHandler().preferredLayoutSize(c);
  375. }
  376. public Dimension minimumLayoutSize(Container c) {
  377. return getHandler().minimumLayoutSize(c);
  378. }
  379. public void layoutContainer(Container c) {
  380. getHandler().layoutContainer(c);
  381. }
  382. }
  383. /// DesktopManager methods
  384. /** Returns the proper DesktopManager. Calls getDesktopPane() to
  385. * find the JDesktop component and returns the desktopManager from
  386. * it. If this fails, it will return a default DesktopManager that
  387. * should work in arbitrary parents.
  388. */
  389. protected DesktopManager getDesktopManager() {
  390. if(frame.getDesktopPane() != null
  391. && frame.getDesktopPane().getDesktopManager() != null)
  392. return frame.getDesktopPane().getDesktopManager();
  393. if(sharedDesktopManager == null)
  394. sharedDesktopManager = createDesktopManager();
  395. return sharedDesktopManager;
  396. }
  397. protected DesktopManager createDesktopManager(){
  398. return new DefaultDesktopManager();
  399. }
  400. /**
  401. * This method is called when the user wants to close the frame.
  402. * The <code>playCloseSound</code> Action is fired.
  403. * This action is delegated to the desktopManager.
  404. */
  405. protected void closeFrame(JInternalFrame f) {
  406. // Internal Frame Auditory Cue Activation
  407. BasicLookAndFeel.playSound(frame,"InternalFrame.closeSound");
  408. // delegate to desktop manager
  409. getDesktopManager().closeFrame(f);
  410. }
  411. /**
  412. * This method is called when the user wants to maximize the frame.
  413. * The <code>playMaximizeSound</code> Action is fired.
  414. * This action is delegated to the desktopManager.
  415. */
  416. protected void maximizeFrame(JInternalFrame f) {
  417. // Internal Frame Auditory Cue Activation
  418. BasicLookAndFeel.playSound(frame,"InternalFrame.maximizeSound");
  419. // delegate to desktop manager
  420. getDesktopManager().maximizeFrame(f);
  421. }
  422. /**
  423. * This method is called when the user wants to minimize the frame.
  424. * The <code>playRestoreDownSound</code> Action is fired.
  425. * This action is delegated to the desktopManager.
  426. */
  427. protected void minimizeFrame(JInternalFrame f) {
  428. // Internal Frame Auditory Cue Activation
  429. if ( ! f.isIcon() ) {
  430. // This method seems to regularly get called after an
  431. // internal frame is iconified. Don't play this sound then.
  432. BasicLookAndFeel.playSound(frame,"InternalFrame.restoreDownSound");
  433. }
  434. // delegate to desktop manager
  435. getDesktopManager().minimizeFrame(f);
  436. }
  437. /**
  438. * This method is called when the user wants to iconify the frame.
  439. * The <code>playMinimizeSound</code> Action is fired.
  440. * This action is delegated to the desktopManager.
  441. */
  442. protected void iconifyFrame(JInternalFrame f) {
  443. // Internal Frame Auditory Cue Activation
  444. BasicLookAndFeel.playSound(frame, "InternalFrame.minimizeSound");
  445. // delegate to desktop manager
  446. getDesktopManager().iconifyFrame(f);
  447. }
  448. /**
  449. * This method is called when the user wants to deiconify the frame.
  450. * The <code>playRestoreUpSound</code> Action is fired.
  451. * This action is delegated to the desktopManager.
  452. */
  453. protected void deiconifyFrame(JInternalFrame f) {
  454. // Internal Frame Auditory Cue Activation
  455. if ( ! f.isMaximum() ) {
  456. // This method seems to regularly get called after an
  457. // internal frame is maximized. Don't play this sound then.
  458. BasicLookAndFeel.playSound(frame, "InternalFrame.restoreUpSound");
  459. }
  460. // delegate to desktop manager
  461. getDesktopManager().deiconifyFrame(f);
  462. }
  463. /** This method is called when the frame becomes selected.
  464. * This action is delegated to the desktopManager.
  465. */
  466. protected void activateFrame(JInternalFrame f) {
  467. getDesktopManager().activateFrame(f);
  468. }
  469. /** This method is called when the frame is no longer selected.
  470. * This action is delegated to the desktopManager.
  471. */
  472. protected void deactivateFrame(JInternalFrame f) {
  473. getDesktopManager().deactivateFrame(f);
  474. }
  475. /////////////////////////////////////////////////////////////////////////
  476. /// Border Listener Class
  477. /////////////////////////////////////////////////////////////////////////
  478. /**
  479. * Listens for border adjustments.
  480. */
  481. protected class BorderListener extends MouseInputAdapter implements SwingConstants
  482. {
  483. // _x & _y are the mousePressed location in absolute coordinate system
  484. int _x, _y;
  485. // __x & __y are the mousePressed location in source view's coordinate system
  486. int __x, __y;
  487. Rectangle startingBounds;
  488. int resizeDir;
  489. protected final int RESIZE_NONE = 0;
  490. private boolean discardRelease = false;
  491. int resizeCornerSize = 16;
  492. public void mouseClicked(MouseEvent e) {
  493. if(e.getClickCount() > 1 && e.getSource() == getNorthPane()) {
  494. if(frame.isIconifiable() && frame.isIcon()) {
  495. try { frame.setIcon(false); } catch (PropertyVetoException e2) { }
  496. } else if(frame.isMaximizable()) {
  497. if(!frame.isMaximum())
  498. try { frame.setMaximum(true); } catch (PropertyVetoException e2) { }
  499. else
  500. try { frame.setMaximum(false); } catch (PropertyVetoException e3) { }
  501. }
  502. }
  503. }
  504. public void mouseReleased(MouseEvent e) {
  505. if (discardRelease) {
  506. discardRelease = false;
  507. return;
  508. }
  509. if (resizeDir == RESIZE_NONE) {
  510. getDesktopManager().endDraggingFrame(frame);
  511. dragging = false;
  512. } else {
  513. Container c = frame.getTopLevelAncestor();
  514. if (c instanceof JFrame) {
  515. ((JFrame)frame.getTopLevelAncestor()).getGlassPane().setCursor(
  516. Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  517. ((JFrame)frame.getTopLevelAncestor()).getGlassPane(
  518. ).setVisible(false);
  519. } else if (c instanceof JApplet) {
  520. ((JApplet)c).getGlassPane().setCursor(
  521. Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  522. ((JApplet)c).getGlassPane().setVisible(false);
  523. } else if (c instanceof JWindow) {
  524. ((JWindow)c).getGlassPane().setCursor(
  525. Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  526. ((JWindow)c).getGlassPane().setVisible(false);
  527. } else if (c instanceof JDialog) {
  528. ((JDialog)c).getGlassPane().setCursor(
  529. Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  530. ((JDialog)c).getGlassPane().setVisible(false);
  531. }
  532. getDesktopManager().endResizingFrame(frame);
  533. }
  534. _x = 0;
  535. _y = 0;
  536. __x = 0;
  537. __y = 0;
  538. startingBounds = null;
  539. resizeDir = RESIZE_NONE;
  540. }
  541. public void mousePressed(MouseEvent e) {
  542. Point p = SwingUtilities.convertPoint((Component)e.getSource(),
  543. e.getX(), e.getY(), null);
  544. __x = e.getX();
  545. __y = e.getY();
  546. _x = p.x;
  547. _y = p.y;
  548. startingBounds = frame.getBounds();
  549. resizeDir = RESIZE_NONE;
  550. if(!frame.isSelected()) {
  551. try { frame.setSelected(true); }
  552. catch (PropertyVetoException e1) { }
  553. }
  554. Insets i = frame.getInsets();
  555. Point ep = new Point(__x, __y);
  556. if (e.getSource() == getNorthPane()) {
  557. Point np = getNorthPane().getLocation();
  558. ep.x += np.x;
  559. ep.y += np.y;
  560. }
  561. if (e.getSource() == getNorthPane()) {
  562. if (ep.x > i.left && ep.y > i.top && ep.x < frame.getWidth() - i.right) {
  563. getDesktopManager().beginDraggingFrame(frame);
  564. dragging = true;
  565. return;
  566. }
  567. }
  568. if (!frame.isResizable()) {
  569. return;
  570. }
  571. if (e.getSource() == frame || e.getSource() == getNorthPane()) {
  572. if (ep.x <= i.left) {
  573. if (ep.y < resizeCornerSize + i.top) {
  574. resizeDir = NORTH_WEST;
  575. } else if (ep.y > frame.getHeight()
  576. - resizeCornerSize - i.bottom) {
  577. resizeDir = SOUTH_WEST;
  578. } else {
  579. resizeDir = WEST;
  580. }
  581. } else if (ep.x >= frame.getWidth() - i.right) {
  582. if (ep.y < resizeCornerSize + i.top) {
  583. resizeDir = NORTH_EAST;
  584. } else if (ep.y > frame.getHeight()
  585. - resizeCornerSize - i.bottom) {
  586. resizeDir = SOUTH_EAST;
  587. } else {
  588. resizeDir = EAST;
  589. }
  590. } else if (ep.y <= i.top) {
  591. if (ep.x < resizeCornerSize + i.left) {
  592. resizeDir = NORTH_WEST;
  593. } else if (ep.x > frame.getWidth()
  594. - resizeCornerSize - i.right) {
  595. resizeDir = NORTH_EAST;
  596. } else {
  597. resizeDir = NORTH;
  598. }
  599. } else if (ep.y >= frame.getHeight() - i.bottom) {
  600. if (ep.x < resizeCornerSize + i.left) {
  601. resizeDir = SOUTH_WEST;
  602. } else if (ep.x > frame.getWidth()
  603. - resizeCornerSize - i.right) {
  604. resizeDir = SOUTH_EAST;
  605. } else {
  606. resizeDir = SOUTH;
  607. }
  608. } else {
  609. /* the mouse press happened inside the frame, not in the
  610. border */
  611. discardRelease = true;
  612. return;
  613. }
  614. Cursor s = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);
  615. switch (resizeDir) {
  616. case SOUTH:
  617. s = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
  618. break;
  619. case NORTH:
  620. s = Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
  621. break;
  622. case WEST:
  623. s = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR);
  624. break;
  625. case EAST:
  626. s = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
  627. break;
  628. case SOUTH_EAST:
  629. s = Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
  630. break;
  631. case SOUTH_WEST:
  632. s = Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR);
  633. break;
  634. case NORTH_WEST:
  635. s = Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR);
  636. break;
  637. case NORTH_EAST:
  638. s = Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR);
  639. break;
  640. }
  641. Container c = frame.getTopLevelAncestor();
  642. if (c instanceof JFrame){
  643. ((JFrame)c).getGlassPane().setVisible(true);
  644. ((JFrame)c).getGlassPane().setCursor(s);
  645. } else if (c instanceof JApplet){
  646. ((JApplet)c).getGlassPane().setVisible(true);
  647. ((JApplet)c).getGlassPane().setCursor(s);
  648. } else if (c instanceof JWindow){
  649. ((JWindow)c).getGlassPane().setVisible(true);
  650. ((JWindow)c).getGlassPane().setCursor(s);
  651. } else if (c instanceof JDialog){
  652. ((JDialog)c).getGlassPane().setVisible(true);
  653. ((JDialog)c).getGlassPane().setCursor(s);
  654. }
  655. getDesktopManager().beginResizingFrame(frame, resizeDir);
  656. return;
  657. }
  658. }
  659. public void mouseDragged(MouseEvent e) {
  660. if ( startingBounds == null ) {
  661. // (STEVE) Yucky work around for bug ID 4106552
  662. return;
  663. }
  664. Point p = SwingUtilities.convertPoint((Component)e.getSource(),
  665. e.getX(), e.getY(), null);
  666. int deltaX = _x - p.x;
  667. int deltaY = _y - p.y;
  668. Dimension min = frame.getMinimumSize();
  669. Dimension max = frame.getMaximumSize();
  670. int newX, newY, newW, newH;
  671. Insets i = frame.getInsets();
  672. // Handle a MOVE
  673. if (dragging) {
  674. if (frame.isMaximum() || ((e.getModifiers() &
  675. InputEvent.BUTTON1_MASK) !=
  676. InputEvent.BUTTON1_MASK)) {
  677. // don't allow moving of frames if maximixed or left mouse
  678. // button was not used.
  679. return;
  680. }
  681. int pWidth, pHeight;
  682. Dimension s = frame.getParent().getSize();
  683. pWidth = s.width;
  684. pHeight = s.height;
  685. newX = startingBounds.x - deltaX;
  686. newY = startingBounds.y - deltaY;
  687. // Make sure we stay in-bounds
  688. if(newX + i.left <= -__x)
  689. newX = -__x - i.left + 1;
  690. if(newY + i.top <= -__y)
  691. newY = -__y - i.top + 1;
  692. if(newX + __x + i.right >= pWidth)
  693. newX = pWidth - __x - i.right - 1;
  694. if(newY + __y + i.bottom >= pHeight)
  695. newY = pHeight - __y - i.bottom - 1;
  696. getDesktopManager().dragFrame(frame, newX, newY);
  697. return;
  698. }
  699. if(!frame.isResizable()) {
  700. return;
  701. }
  702. newX = frame.getX();
  703. newY = frame.getY();
  704. newW = frame.getWidth();
  705. newH = frame.getHeight();
  706. parentBounds = frame.getParent().getBounds();
  707. switch(resizeDir) {
  708. case RESIZE_NONE:
  709. return;
  710. case NORTH:
  711. if(startingBounds.height + deltaY < min.height)
  712. deltaY = -(startingBounds.height - min.height);
  713. else if(startingBounds.height + deltaY > max.height)
  714. deltaY = max.height - startingBounds.height;
  715. if (startingBounds.y - deltaY < 0) {deltaY = startingBounds.y;}
  716. newX = startingBounds.x;
  717. newY = startingBounds.y - deltaY;
  718. newW = startingBounds.width;
  719. newH = startingBounds.height + deltaY;
  720. break;
  721. case NORTH_EAST:
  722. if(startingBounds.height + deltaY < min.height)
  723. deltaY = -(startingBounds.height - min.height);
  724. else if(startingBounds.height + deltaY > max.height)
  725. deltaY = max.height - startingBounds.height;
  726. if (startingBounds.y - deltaY < 0) {deltaY = startingBounds.y;}
  727. if(startingBounds.width - deltaX < min.width)
  728. deltaX = startingBounds.width - min.width;
  729. else if(startingBounds.width - deltaX > max.width)
  730. deltaX = -(max.width - startingBounds.width);
  731. if (startingBounds.x + startingBounds.width - deltaX >
  732. parentBounds.width) {
  733. deltaX = startingBounds.x + startingBounds.width -
  734. parentBounds.width;
  735. }
  736. newX = startingBounds.x;
  737. newY = startingBounds.y - deltaY;
  738. newW = startingBounds.width - deltaX;
  739. newH = startingBounds.height + deltaY;
  740. break;
  741. case EAST:
  742. if(startingBounds.width - deltaX < min.width)
  743. deltaX = startingBounds.width - min.width;
  744. else if(startingBounds.width - deltaX > max.width)
  745. deltaX = -(max.width - startingBounds.width);
  746. if (startingBounds.x + startingBounds.width - deltaX >
  747. parentBounds.width) {
  748. deltaX = startingBounds.x + startingBounds.width -
  749. parentBounds.width;
  750. }
  751. newW = startingBounds.width - deltaX;
  752. newH = startingBounds.height;
  753. break;
  754. case SOUTH_EAST:
  755. if(startingBounds.width - deltaX < min.width)
  756. deltaX = startingBounds.width - min.width;
  757. else if(startingBounds.width - deltaX > max.width)
  758. deltaX = -(max.width - startingBounds.width);
  759. if (startingBounds.x + startingBounds.width - deltaX >
  760. parentBounds.width) {
  761. deltaX = startingBounds.x + startingBounds.width -
  762. parentBounds.width;
  763. }
  764. if(startingBounds.height - deltaY < min.height)
  765. deltaY = startingBounds.height - min.height;
  766. else if(startingBounds.height - deltaY > max.height)
  767. deltaY = -(max.height - startingBounds.height);
  768. if (startingBounds.y + startingBounds.height - deltaY >
  769. parentBounds.height) {
  770. deltaY = startingBounds.y + startingBounds.height -
  771. parentBounds.height ;
  772. }
  773. newW = startingBounds.width - deltaX;
  774. newH = startingBounds.height - deltaY;
  775. break;
  776. case SOUTH:
  777. if(startingBounds.height - deltaY < min.height)
  778. deltaY = startingBounds.height - min.height;
  779. else if(startingBounds.height - deltaY > max.height)
  780. deltaY = -(max.height - startingBounds.height);
  781. if (startingBounds.y + startingBounds.height - deltaY >
  782. parentBounds.height) {
  783. deltaY = startingBounds.y + startingBounds.height -
  784. parentBounds.height ;
  785. }
  786. newW = startingBounds.width;
  787. newH = startingBounds.height - deltaY;
  788. break;
  789. case SOUTH_WEST:
  790. if(startingBounds.height - deltaY < min.height)
  791. deltaY = startingBounds.height - min.height;
  792. else if(startingBounds.height - deltaY > max.height)
  793. deltaY = -(max.height - startingBounds.height);
  794. if (startingBounds.y + startingBounds.height - deltaY >
  795. parentBounds.height) {
  796. deltaY = startingBounds.y + startingBounds.height -
  797. parentBounds.height ;
  798. }
  799. if(startingBounds.width + deltaX < min.width)
  800. deltaX = -(startingBounds.width - min.width);
  801. else if(startingBounds.width + deltaX > max.width)
  802. deltaX = max.width - startingBounds.width;
  803. if (startingBounds.x - deltaX < 0) {
  804. deltaX = startingBounds.x;
  805. }
  806. newX = startingBounds.x - deltaX;
  807. newY = startingBounds.y;
  808. newW = startingBounds.width + deltaX;
  809. newH = startingBounds.height - deltaY;
  810. break;
  811. case WEST:
  812. if(startingBounds.width + deltaX < min.width)
  813. deltaX = -(startingBounds.width - min.width);
  814. else if(startingBounds.width + deltaX > max.width)
  815. deltaX = max.width - startingBounds.width;
  816. if (startingBounds.x - deltaX < 0) {
  817. deltaX = startingBounds.x;
  818. }
  819. newX = startingBounds.x - deltaX;
  820. newY = startingBounds.y;
  821. newW = startingBounds.width + deltaX;
  822. newH = startingBounds.height;
  823. break;
  824. case NORTH_WEST:
  825. if(startingBounds.width + deltaX < min.width)
  826. deltaX = -(startingBounds.width - min.width);
  827. else if(startingBounds.width + deltaX > max.width)
  828. deltaX = max.width - startingBounds.width;
  829. if (startingBounds.x - deltaX < 0) {
  830. deltaX = startingBounds.x;
  831. }
  832. if(startingBounds.height + deltaY < min.height)
  833. deltaY = -(startingBounds.height - min.height);
  834. else if(startingBounds.height + deltaY > max.height)
  835. deltaY = max.height - startingBounds.height;
  836. if (startingBounds.y - deltaY < 0) {deltaY = startingBounds.y;}
  837. newX = startingBounds.x - deltaX;
  838. newY = startingBounds.y - deltaY;
  839. newW = startingBounds.width + deltaX;
  840. newH = startingBounds.height + deltaY;
  841. break;
  842. default:
  843. return;
  844. }
  845. getDesktopManager().resizeFrame(frame, newX, newY, newW, newH);
  846. }
  847. public void mouseMoved(MouseEvent e) {
  848. if(!frame.isResizable())
  849. return;
  850. if (e.getSource() == frame || e.getSource() == getNorthPane()) {
  851. Insets i = frame.getInsets();
  852. Point ep = new Point(e.getX(), e.getY());
  853. if (e.getSource() == getNorthPane()) {
  854. Point np = getNorthPane().getLocation();
  855. ep.x += np.x;
  856. ep.y += np.y;
  857. }
  858. if(ep.x <= i.left) {
  859. if(ep.y < resizeCornerSize + i.top)
  860. frame.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
  861. else if(ep.y > frame.getHeight() - resizeCornerSize - i.bottom)
  862. frame.setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
  863. else
  864. frame.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
  865. } else if(ep.x >= frame.getWidth() - i.right) {
  866. if(e.getY() < resizeCornerSize + i.top)
  867. frame.setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
  868. else if(ep.y > frame.getHeight() - resizeCornerSize - i.bottom)
  869. frame.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
  870. else
  871. frame.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
  872. } else if(ep.y <= i.top) {
  873. if(ep.x < resizeCornerSize + i.left)
  874. frame.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
  875. else if(ep.x > frame.getWidth() - resizeCornerSize - i.right)
  876. frame.setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
  877. else
  878. frame.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
  879. } else if(ep.y >= frame.getHeight() - i.bottom) {
  880. if(ep.x < resizeCornerSize + i.left)
  881. frame.setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
  882. else if(ep.x > frame.getWidth() - resizeCornerSize - i.right)
  883. frame.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
  884. else
  885. frame.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
  886. }
  887. else
  888. frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); return;
  889. }
  890. frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  891. }
  892. public void mouseExited(MouseEvent e) {
  893. frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  894. }
  895. }; /// End BorderListener Class
  896. protected class ComponentHandler implements ComponentListener {
  897. // NOTE: This class exists only for backward compatability. All
  898. // its functionality has been moved into Handler. If you need to add
  899. // new functionality add it to the Handler, but make sure this
  900. // class calls into the Handler.
  901. /** Invoked when a JInternalFrame's parent's size changes. */
  902. public void componentResized(ComponentEvent e) {
  903. getHandler().componentResized(e);
  904. }
  905. public void componentMoved(ComponentEvent e) {
  906. getHandler().componentMoved(e);
  907. }
  908. public void componentShown(ComponentEvent e) {
  909. getHandler().componentShown(e);
  910. }
  911. public void componentHidden(ComponentEvent e) {
  912. getHandler().componentHidden(e);
  913. }
  914. }
  915. protected ComponentListener createComponentListener() {
  916. return getHandler();
  917. }
  918. protected class GlassPaneDispatcher implements MouseInputListener {
  919. // NOTE: This class exists only for backward compatability. All
  920. // its functionality has been moved into Handler. If you need to add
  921. // new functionality add it to the Handler, but make sure this
  922. // class calls into the Handler.
  923. public void mousePressed(MouseEvent e) {
  924. getHandler().mousePressed(e);
  925. }
  926. public void mouseEntered(MouseEvent e) {
  927. getHandler().mouseEntered(e);
  928. }
  929. public void mouseMoved(MouseEvent e) {
  930. getHandler().mouseMoved(e);
  931. }
  932. public void mouseExited(MouseEvent e) {
  933. getHandler().mouseExited(e);
  934. }
  935. public void mouseClicked(MouseEvent e) {
  936. getHandler().mouseClicked(e);
  937. }
  938. public void mouseReleased(MouseEvent e) {
  939. getHandler().mouseReleased(e);
  940. }
  941. public void mouseDragged(MouseEvent e) {
  942. getHandler().mouseDragged(e);
  943. }
  944. }
  945. protected MouseInputListener createGlassPaneDispatcher() {
  946. return getHandler();
  947. }
  948. protected class BasicInternalFrameListener implements InternalFrameListener
  949. {
  950. // NOTE: This class exists only for backward compatability. All
  951. // its functionality has been moved into Handler. If you need to add
  952. // new functionality add it to the Handler, but make sure this
  953. // class calls into the Handler.
  954. public void internalFrameClosing(InternalFrameEvent e) {
  955. getHandler().internalFrameClosing(e);
  956. }
  957. public void internalFrameClosed(InternalFrameEvent e) {
  958. getHandler().internalFrameClosed(e);
  959. }
  960. public void internalFrameOpened(InternalFrameEvent e) {
  961. getHandler().internalFrameOpened(e);
  962. }
  963. public void internalFrameIconified(InternalFrameEvent e) {
  964. getHandler().internalFrameIconified(e);
  965. }
  966. public void internalFrameDeiconified(InternalFrameEvent e) {
  967. getHandler().internalFrameDeiconified(e);
  968. }
  969. public void internalFrameActivated(InternalFrameEvent e) {
  970. getHandler().internalFrameActivated(e);
  971. }
  972. public void internalFrameDeactivated(InternalFrameEvent e) {
  973. getHandler().internalFrameDeactivated(e);
  974. }
  975. }
  976. private static boolean isDragging = false;
  977. private class Handler implements ComponentListener, InternalFrameListener,
  978. LayoutManager, MouseInputListener, PropertyChangeListener,
  979. SwingConstants {
  980. // ComponentHandler methods
  981. /** Invoked when a JInternalFrame's parent's size changes. */
  982. public void componentResized(ComponentEvent e) {
  983. // Get the JInternalFrame's parent container size
  984. Rectangle parentNewBounds = ((Component) e.getSource()).getBounds();
  985. JInternalFrame.JDesktopIcon icon = null;
  986. if (frame != null) {
  987. icon = frame.getDesktopIcon();
  988. // Resize the internal frame if it is maximized and relocate
  989. // the associated icon as well.
  990. if (frame.isMaximum()) {
  991. frame.setBounds(0, 0, parentNewBounds.width,
  992. parentNewBounds.height);
  993. }
  994. }
  995. // Relocate the icon base on the new parent bounds.
  996. if (icon != null) {
  997. Rectangle iconBounds = icon.getBounds();
  998. int y = iconBounds.y +
  999. (parentNewBounds.height - parentBounds.height);
  1000. icon.setBounds(iconBounds.x, y,
  1001. iconBounds.width, iconBounds.height);
  1002. }
  1003. // Update the new parent bounds for next resize.
  1004. if (!parentBounds.equals(parentNewBounds)) {
  1005. parentBounds = parentNewBounds;
  1006. }
  1007. // Validate the component tree for this container.
  1008. if (frame != null) frame.validate();
  1009. }
  1010. public void componentMoved(ComponentEvent e) {}
  1011. public void componentShown(ComponentEvent e) {}
  1012. public void componentHidden(ComponentEvent e) {}
  1013. // InternalFrameListener
  1014. public void internalFrameClosed(InternalFrameEvent e) {
  1015. frame.removeInternalFrameListener(getHandler());
  1016. }
  1017. public void internalFrameActivated(InternalFrameEvent e) {
  1018. if (!isKeyBindingRegistered()){
  1019. setKeyBindingRegistered(true);
  1020. setupMenuOpenKey();
  1021. setupMenuCloseKey();
  1022. }
  1023. if (isKeyBindingRegistered())
  1024. setKeyBindingActive(true);
  1025. }
  1026. public void internalFrameDeactivated(InternalFrameEvent e) {
  1027. setKeyBindingActive(false);
  1028. }
  1029. public void internalFrameClosing(InternalFrameEvent e) { }
  1030. public void internalFrameOpened(InternalFrameEvent e) { }
  1031. public void internalFrameIconified(InternalFrameEvent e) { }
  1032. public void internalFrameDeiconified(InternalFrameEvent e) { }
  1033. // LayoutManager
  1034. public void addLayoutComponent(String name, Component c) {}
  1035. public void removeLayoutComponent(Component c) {}
  1036. public Dimension preferredLayoutSize(Container c) {
  1037. Dimension result;
  1038. Insets i = frame.getInsets();
  1039. result = new Dimension(frame.getRootPane().getPreferredSize());
  1040. result.width += i.left + i.right;
  1041. result.height += i.top + i.bottom;
  1042. if(getNorthPane() != null) {
  1043. Dimension d = getNorthPane().getPreferredSize();
  1044. result.width = Math.max(d.width, result.width);
  1045. result.height += d.height;
  1046. }
  1047. if(getSouthPane() != null) {
  1048. Dimension d = getSouthPane().getPreferredSize();
  1049. result.width = Math.max(d.width, result.width);
  1050. result.height += d.height;
  1051. }
  1052. if(getEastPane() != null) {
  1053. Dimension d = getEastPane().getPreferredSize();
  1054. result.width += d.width;
  1055. result.height = Math.max(d.height, result.height);
  1056. }
  1057. if(getWestPane() != null) {
  1058. Dimension d = getWestPane().getPreferredSize();
  1059. result.width += d.width;
  1060. result.height = Math.max(d.height, result.height);
  1061. }
  1062. return result;
  1063. }
  1064. public Dimension minimumLayoutSize(Container c) {
  1065. // The minimum size of the internal frame only takes into
  1066. // account the title pane since you are allowed to resize
  1067. // the frames to the point where just the title pane is visible.
  1068. Dimension result = new Dimension();
  1069. if (getNorthPane() != null &&
  1070. getNorthPane() instanceof BasicInternalFrameTitlePane) {
  1071. result = new Dimension(getNorthPane().getMinimumSize());
  1072. }
  1073. Insets i = frame.getInsets();
  1074. result.width += i.left + i.right;
  1075. result.height += i.top + i.bottom;
  1076. return result;
  1077. }
  1078. public void layoutContainer(Container c) {
  1079. Insets i = frame.getInsets();
  1080. int cx, cy, cw, ch;
  1081. cx = i.left;
  1082. cy = i.top;
  1083. cw = frame.getWidth() - i.left - i.right;
  1084. ch = frame.getHeight() - i.top - i.bottom;
  1085. if(getNorthPane() != null) {
  1086. Dimension size = getNorthPane().getPreferredSize();
  1087. if (DefaultLookup.getBoolean(frame, BasicInternalFrameUI.this,
  1088. "InternalFrame.layoutTitlePaneAtOrigin", false)) {
  1089. cy = 0;
  1090. ch += i.top;
  1091. getNorthPane().setBounds(0, 0, frame.getWidth(),
  1092. size.height);
  1093. }
  1094. else {
  1095. getNorthPane().setBounds(cx, cy, cw, size.height);
  1096. }
  1097. cy += size.height;
  1098. ch -= size.height;
  1099. }
  1100. if(getSouthPane() != null) {
  1101. Dimension size = getSouthPane().getPreferredSize();
  1102. getSouthPane().setBounds(cx, frame.getHeight()
  1103. - i.bottom - size.height,
  1104. cw, size.height);
  1105. ch -= size.height;
  1106. }
  1107. if(getWestPane() != null) {
  1108. Dimension size = getWestPane().getPreferredSize();
  1109. getWestPane().setBounds(cx, cy, size.width, ch);
  1110. cw -= size.width;
  1111. cx += size.width;
  1112. }
  1113. if(getEastPane() != null) {
  1114. Dimension size = getEastPane().getPreferredSize();
  1115. getEastPane().setBounds(cw - size.width, cy, size.width, ch);
  1116. cw -= size.width;
  1117. }
  1118. if(frame.getRootPane() != null) {
  1119. frame.getRootPane().setBounds(cx, cy, cw, ch);
  1120. }
  1121. }
  1122. // MouseInputListener
  1123. private Component mouseEventTarget = null;
  1124. private Component dragSource = null;
  1125. public void mousePressed(MouseEvent e) {
  1126. // what is going on here is the GlassPane is up on the inactive
  1127. // internalframe and want's to "catch" the first mousePressed on
  1128. // the frame in order to give it to the BorderLister (and not the
  1129. // underlying component) and let it activate the frame
  1130. if (borderListener != null){
  1131. borderListener.mousePressed(e);
  1132. }
  1133. forwardMouseEvent(e);
  1134. }
  1135. /**
  1136. * Forward the mouseEntered event to the underlying child container.
  1137. * @see #mousePressed
  1138. */
  1139. public void mouseEntered(MouseEvent e) {
  1140. forwardMouseEvent(e);
  1141. }
  1142. /**
  1143. * Forward the mouseMoved event to the underlying child container.
  1144. * @see #mousePressed
  1145. */
  1146. public void mouseMoved(MouseEvent e) {
  1147. forwardMouseEvent(e);
  1148. }
  1149. /**
  1150. * Forward the mouseExited event to the underlying child container.
  1151. * @see #mousePressed
  1152. */
  1153. public void mouseExited(MouseEvent e) {
  1154. forwardMouseEvent(e);
  1155. }
  1156. /**
  1157. * Ignore mouseClicked events.
  1158. * @see #mousePressed
  1159. */
  1160. public void mouseClicked(MouseEvent e) { }
  1161. /**
  1162. * Forward the mouseReleased event to the underlying child container.
  1163. * @see #mousePressed
  1164. */
  1165. public void mouseReleased(MouseEvent e) {
  1166. forwardMouseEvent(e);
  1167. }
  1168. /**
  1169. * Forward the mouseDragged event to the underlying child container.
  1170. * @see #mousePressed
  1171. */
  1172. public void mouseDragged(MouseEvent e) {
  1173. forwardMouseEvent(e);
  1174. }
  1175. /**
  1176. * Forward a mouse event to the current mouse target, setting it
  1177. * if necessary.
  1178. */
  1179. private void forwardMouseEvent(MouseEvent e) {
  1180. // We only want to do this for the selected internal frame.
  1181. Component target =
  1182. findComponentAt(frame.getRootPane().getLayeredPane(),
  1183. e.getX(), e.getY());
  1184. // Search hierarchy for target with mouse listeners.
  1185. while ((target != null) &&
  1186. ((target.getMouseListeners().length == 0) &&
  1187. (target.getMouseMotionListeners().length == 0) &&
  1188. (target.getMouseWheelListeners().length == 0))) {
  1189. target = target.getParent();
  1190. }
  1191. if (target == null) {
  1192. // No target found with mouse listeners.
  1193. return;
  1194. }
  1195. int id = e.getID();
  1196. switch(id) {
  1197. case MouseEvent.MOUSE_ENTERED:
  1198. if (isDragging && !frame.isSelected()) {
  1199. return;
  1200. }
  1201. if (target != mouseEventTarget) {
  1202. mouseEventTarget = target;
  1203. }
  1204. retargetMouseEvent(id, e, mouseEventTarget);
  1205. break;
  1206. case MouseEvent.MOUSE_PRESSED:
  1207. if (target != mouseEventTarget) {
  1208. mouseEventTarget = target;
  1209. }
  1210. retargetMouseEvent(id, e, mouseEventTarget);
  1211. // Set the drag source in case we start dragging.
  1212. dragSource = target;
  1213. break;
  1214. case MouseEvent.MOUSE_EXITED:
  1215. if (isDragging && !frame.isSelected()) {
  1216. return;
  1217. }
  1218. retargetMouseEvent(id, e, mouseEventTarget);
  1219. break;
  1220. case MouseEvent.MOUSE_CLICKED:
  1221. retargetMouseEvent(id, e, mouseEventTarget);
  1222. break;
  1223. case MouseEvent.MOUSE_MOVED:
  1224. if (target != mouseEventTarget) {
  1225. retargetMouseEvent(MouseEvent.MOUSE_EXITED, e,
  1226. mouseEventTarget);
  1227. mouseEventTarget = target;
  1228. retargetMouseEvent(MouseEvent.MOUSE_ENTERED, e,
  1229. mouseEventTarget);
  1230. }
  1231. retargetMouseEvent(id, e, mouseEventTarget);
  1232. break;
  1233. case MouseEvent.MOUSE_DRAGGED:
  1234. if (!isDragging) {
  1235. isDragging = true;
  1236. }
  1237. retargetMouseEvent(id, e, dragSource);
  1238. break;
  1239. case MouseEvent.MOUSE_RELEASED:
  1240. if (isDragging) {
  1241. retargetMouseEvent(id, e, dragSource);
  1242. isDragging = false;
  1243. } else {
  1244. retargetMouseEvent(id, e, mouseEventTarget);
  1245. }
  1246. break;
  1247. case MouseEvent.MOUSE_WHEEL:
  1248. retargetMouseEvent(id, e, mouseEventTarget);
  1249. break;
  1250. }
  1251. }
  1252. /**
  1253. * Find the lightweight child component which corresponds to the
  1254. * specified location. This is similar to the new 1.2 API in
  1255. * Container, but we need to run on 1.1. The other changes are
  1256. * due to Container.findComponentAt's use of package-private data.
  1257. */
  1258. private Component findComponentAt(Container c, int x, int y) {
  1259. if (!c.contains(x, y)) {
  1260. return c;
  1261. }
  1262. int ncomponents = c.getComponentCount();
  1263. Component component[] = c.getComponents();
  1264. for (int i = 0 ; i < ncomponents ; i++) {
  1265. Component comp = component[i];
  1266. Point loc = comp.getLocation();
  1267. if ((comp != null) && (comp.contains(x - loc.x, y - loc.y)) &&
  1268. (comp.getPeer() instanceof LightweightPeer) &&
  1269. (comp.isVisible() == true)) {
  1270. // found a component that intersects the point, see if there
  1271. // is a deeper possibility.
  1272. if (comp instanceof Container) {
  1273. Container child = (Container) comp;
  1274. Point childLoc = child.getLocation();
  1275. Component deeper = findComponentAt(child,
  1276. x - childLoc.x, y - childLoc.y);
  1277. if (deeper != null) {
  1278. return deeper;
  1279. }
  1280. } else {
  1281. return comp;
  1282. }
  1283. }
  1284. }
  1285. return c;
  1286. }
  1287. /**
  1288. * Dispatch an event clone, retargeted for the specified target.
  1289. */
  1290. private void retargetMouseEvent(int id, MouseEvent e,
  1291. Component target) {
  1292. if (target == null) {
  1293. return;
  1294. }
  1295. // fix for bug #4202966 -- hania
  1296. // When retargetting a mouse event, we need to translate
  1297. // the event's coordinates relative to the target.
  1298. Point p = SwingUtilities.convertPoint(frame.getLayeredPane(),
  1299. e.getX(), e.getY(),
  1300. target);
  1301. MouseEvent retargeted = new MouseEvent(target,
  1302. id,
  1303. e.getWhen(),
  1304. e.getModifiers() | e.getModifiersEx(),
  1305. p.x,
  1306. p.y,
  1307. e.getClickCount(),
  1308. e.isPopupTrigger());
  1309. target.dispatchEvent(retargeted);
  1310. }
  1311. // PropertyChangeListener
  1312. public void propertyChange(PropertyChangeEvent evt) {
  1313. String prop = (String)evt.getPropertyName();
  1314. JInternalFrame f = (JInternalFrame)evt.getSource();
  1315. Object newValue = evt.getNewValue();
  1316. Object oldValue = evt.getOldValue();
  1317. if (JInternalFrame.IS_CLOSED_PROPERTY == prop) {
  1318. if (newValue == Boolean.TRUE) {
  1319. if ((frame.getParent() != null) && componentListenerAdded) {
  1320. frame.getParent().removeComponentListener(
  1321. componentListener);
  1322. }
  1323. closeFrame(f);
  1324. }
  1325. } else if (JInternalFrame.IS_MAXIMUM_PROPERTY == prop) {
  1326. if(newValue == Boolean.TRUE) {
  1327. maximizeFrame(f);
  1328. } else {
  1329. minimizeFrame(f);
  1330. }
  1331. } else if(JInternalFrame.IS_ICON_PROPERTY == prop) {
  1332. if (newValue == Boolean.TRUE) {
  1333. iconifyFrame(f);
  1334. } else {
  1335. deiconifyFrame(f);
  1336. }
  1337. } else if (JInternalFrame.IS_SELECTED_PROPERTY == prop) {
  1338. Component glassPane = f.getGlassPane();
  1339. if (newValue == Boolean.TRUE && oldValue == Boolean.FALSE) {
  1340. activateFrame(f);
  1341. glassPane.setVisible(false);
  1342. } else if (newValue == Boolean.FALSE &&
  1343. oldValue == Boolean.TRUE) {
  1344. deactivateFrame(f);
  1345. glassPane.setVisible(true);
  1346. }
  1347. } else if (prop == "ancestor") {
  1348. if (frame.getParent() != null) {
  1349. parentBounds = f.getParent().getBounds();
  1350. } else {
  1351. parentBounds = null;
  1352. }
  1353. if ((frame.getParent() != null) && !componentListenerAdded) {
  1354. f.getParent().addComponentListener(componentListener);
  1355. componentListenerAdded = true;
  1356. } else if ((newValue == null) && componentListenerAdded) {
  1357. if (f.getParent() != null) {
  1358. f.getParent().removeComponentListener(
  1359. componentListener);
  1360. }
  1361. componentListenerAdded = false;
  1362. }
  1363. } else if (JInternalFrame.TITLE_PROPERTY == prop ||
  1364. prop == "closable" || prop == "iconable" ||
  1365. prop == "maximizable") {
  1366. Dimension dim = frame.getMinimumSize();
  1367. Dimension frame_dim = frame.getSize();
  1368. if (dim.width > frame_dim.width) {
  1369. frame.setSize(dim.width, frame_dim.height);
  1370. }
  1371. }
  1372. }
  1373. }
  1374. }