1. /*
  2. * @(#)BasicInternalFrameUI.java 1.75 01/03/13
  3. *
  4. * Copyright 1997-2001 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.basic;
  11. import java.awt.*;
  12. import java.awt.event.*;
  13. import javax.swing.*;
  14. import javax.swing.border.*;
  15. import javax.swing.plaf.*;
  16. import javax.swing.event.*;
  17. import java.beans.*;
  18. import java.io.Serializable;
  19. /**
  20. * A basic L&F implementation of JInternalFrame.
  21. *
  22. * @version 1.75 03/13/01
  23. * @author David Kloba
  24. * @author Rich Schiavi
  25. */
  26. public class BasicInternalFrameUI extends InternalFrameUI
  27. {
  28. protected JInternalFrame frame;
  29. protected MouseInputAdapter borderListener;
  30. protected PropertyChangeListener propertyChangeListener;
  31. protected LayoutManager internalFrameLayout;
  32. protected ComponentListener componentListener;
  33. protected MouseInputListener glassPaneDispatcher;
  34. protected JComponent northPane;
  35. protected JComponent southPane;
  36. protected JComponent westPane;
  37. protected JComponent eastPane;
  38. protected BasicInternalFrameTitlePane titlePane; // access needs this
  39. private static DesktopManager sharedDesktopManager;
  40. private boolean componentListenerAdded = false;
  41. private Rectangle parentBounds = null;
  42. /**
  43. * As of Java 2 platform v1.3 this previously undocumented field is no
  44. * longer used.
  45. * Key bindings are now defined by the LookAndFeel, please refer to
  46. * the key bindings specification for further details.
  47. *
  48. * @deprecated As of Java 2 platform v1.3.
  49. */
  50. protected KeyStroke openMenuKey;
  51. private boolean keyBindingRegistered = false;
  52. private boolean keyBindingActive = false;
  53. private InternalFrameListener internalFrameListener = null;
  54. /////////////////////////////////////////////////////////////////////////////
  55. // ComponentUI Interface Implementation methods
  56. /////////////////////////////////////////////////////////////////////////////
  57. public static ComponentUI createUI(JComponent b) {
  58. return new BasicInternalFrameUI((JInternalFrame)b);
  59. }
  60. public BasicInternalFrameUI(JInternalFrame b) {
  61. }
  62. public void installUI(JComponent c) {
  63. frame = (JInternalFrame)c;
  64. frame.add(frame.getRootPane(), "Center");
  65. installDefaults();
  66. installComponents();
  67. installListeners();
  68. installKeyboardActions();
  69. setNorthPane(createNorthPane(frame));
  70. setSouthPane(createSouthPane(frame));
  71. setEastPane(createEastPane(frame));
  72. setWestPane(createWestPane(frame));
  73. frame.setOpaque(true);
  74. int height = (getNorthPane() != null ?
  75. getNorthPane().getMinimumSize().height : 0) +
  76. frame.getInsets().top + frame.getInsets().bottom;
  77. frame.setMinimumSize(new Dimension(120, height));
  78. }
  79. public void uninstallUI(JComponent c) {
  80. if(c != frame)
  81. throw new IllegalComponentStateException(
  82. this + " was asked to deinstall() "
  83. + c + " when it only knows about "
  84. + frame + ".");
  85. uninstallDefaults();
  86. uninstallComponents();
  87. frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  88. setNorthPane(null);
  89. setSouthPane(null);
  90. setEastPane(null);
  91. setWestPane(null);
  92. uninstallListeners();
  93. uninstallKeyboardActions();
  94. frame.remove(frame.getRootPane());
  95. frame = null;
  96. }
  97. protected void installDefaults(){
  98. Icon frameIcon = frame.getFrameIcon();
  99. if (frameIcon == null || frameIcon instanceof UIResource) {
  100. frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon"));
  101. }
  102. /* enable the content pane to inherit background color from its
  103. parent by setting its background color to null. Fixes bug#
  104. 4268949. */
  105. JComponent contentPane = (JComponent) frame.getContentPane();
  106. if (contentPane != null) {
  107. Color bg = contentPane.getBackground();
  108. if (bg instanceof UIResource)
  109. contentPane.setBackground(null);
  110. }
  111. LookAndFeel.installBorder(frame, "InternalFrame.border");
  112. }
  113. protected void installKeyboardActions(){
  114. if (internalFrameListener == null)
  115. createInternalFrameListener();
  116. frame.addInternalFrameListener(internalFrameListener);
  117. }
  118. protected void installComponents(){}
  119. protected void installListeners(){
  120. borderListener = createBorderListener(frame);
  121. propertyChangeListener = createPropertyChangeListener();
  122. frame.addPropertyChangeListener(propertyChangeListener);
  123. frame.setLayout(internalFrameLayout = createLayoutManager());
  124. installMouseHandlers(frame);
  125. glassPaneDispatcher = createGlassPaneDispatcher();
  126. frame.getGlassPane().addMouseListener(glassPaneDispatcher);
  127. frame.getGlassPane().addMouseMotionListener(glassPaneDispatcher);
  128. componentListener = createComponentListener();
  129. if ((frame.getParent() != null) && !componentListenerAdded) {
  130. frame.getParent().addComponentListener(componentListener);
  131. componentListenerAdded = true;
  132. parentBounds = frame.getParent().getBounds();
  133. }
  134. }
  135. InputMap getInputMap(int condition) {
  136. if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
  137. return createInputMap(condition);
  138. }
  139. return null;
  140. }
  141. InputMap createInputMap(int condition) {
  142. if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
  143. Object[] bindings = (Object[])UIManager.get
  144. ("InternalFrame.windowBindings");
  145. if (bindings != null) {
  146. return LookAndFeel.makeComponentInputMap(frame, bindings);
  147. }
  148. }
  149. return null;
  150. }
  151. ActionMap getActionMap() {
  152. return createActionMap();
  153. }
  154. ActionMap createActionMap() {
  155. ActionMap map = new ActionMapUIResource();
  156. map.put("showSystemMenu", new AbstractAction(){
  157. public void actionPerformed(ActionEvent e){
  158. titlePane.showSystemMenu();
  159. }
  160. public boolean isEnabled(){
  161. return isKeyBindingActive();
  162. }
  163. });
  164. return map;
  165. }
  166. protected void uninstallDefaults() {
  167. Icon frameIcon = frame.getFrameIcon();
  168. if (frameIcon instanceof UIResource) {
  169. frame.setFrameIcon(null);
  170. }
  171. LookAndFeel.uninstallBorder(frame);
  172. }
  173. protected void uninstallComponents(){
  174. }
  175. protected void uninstallListeners(){
  176. deinstallMouseHandlers(frame);
  177. frame.removePropertyChangeListener(propertyChangeListener);
  178. frame.setLayout(null);
  179. internalFrameLayout = null;
  180. propertyChangeListener = null;
  181. frame.getGlassPane().removeMouseListener(glassPaneDispatcher);
  182. frame.getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
  183. if ((frame.getParent() != null) && componentListenerAdded) {
  184. frame.getParent().removeComponentListener(componentListener);
  185. componentListenerAdded=false;
  186. }
  187. glassPaneDispatcher = null;
  188. componentListener = null;
  189. borderListener = null;
  190. }
  191. protected void uninstallKeyboardActions(){
  192. if (internalFrameListener != null)
  193. frame.removeInternalFrameListener(internalFrameListener);
  194. if (isKeyBindingRegistered()){
  195. SwingUtilities.replaceUIInputMap(frame, JComponent.
  196. WHEN_IN_FOCUSED_WINDOW, null);
  197. SwingUtilities.replaceUIActionMap(frame, null);
  198. }
  199. }
  200. protected LayoutManager createLayoutManager(){
  201. return new InternalFrameLayout();
  202. }
  203. protected PropertyChangeListener createPropertyChangeListener(){
  204. return new InternalFramePropertyChangeListener();
  205. }
  206. public Dimension getPreferredSize(JComponent x) {
  207. if((JComponent)frame == x)
  208. return frame.getLayout().preferredLayoutSize(x);
  209. return new Dimension(100, 100);
  210. }
  211. public Dimension getMinimumSize(JComponent x) {
  212. if((JComponent)frame == x)
  213. return frame.getLayout().minimumLayoutSize(x);
  214. return new Dimension(0, 0);
  215. }
  216. public Dimension getMaximumSize(JComponent x) {
  217. return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
  218. }
  219. /** Adds necessary mouseHandlers to currentPane and adds it to frame.
  220. * Reverse process for the newPane.
  221. */
  222. protected void replacePane(JComponent currentPane, JComponent newPane) {
  223. if(currentPane != null) {
  224. deinstallMouseHandlers(currentPane);
  225. frame.remove(currentPane);
  226. }
  227. if(newPane != null) {
  228. frame.add(newPane);
  229. installMouseHandlers(newPane);
  230. }
  231. }
  232. protected void deinstallMouseHandlers(JComponent c) {
  233. c.removeMouseListener(borderListener);
  234. c.removeMouseMotionListener(borderListener);
  235. }
  236. protected void installMouseHandlers(JComponent c) {
  237. c.addMouseListener(borderListener);
  238. c.addMouseMotionListener(borderListener);
  239. }
  240. protected JComponent createNorthPane(JInternalFrame w) {
  241. titlePane = new BasicInternalFrameTitlePane(w);
  242. return titlePane;
  243. }
  244. protected JComponent createSouthPane(JInternalFrame w) {
  245. return null;
  246. }
  247. protected JComponent createWestPane(JInternalFrame w) {
  248. return null;
  249. }
  250. protected JComponent createEastPane(JInternalFrame w) {
  251. return null;
  252. }
  253. protected MouseInputAdapter createBorderListener(JInternalFrame w) {
  254. return new BorderListener();
  255. }
  256. private InternalFrameListener getInternalFrameListener(){
  257. return internalFrameListener;
  258. }
  259. protected void createInternalFrameListener(){
  260. internalFrameListener = new BasicInternalFrameListener();
  261. }
  262. protected final boolean isKeyBindingRegistered(){
  263. return keyBindingRegistered;
  264. }
  265. protected final void setKeyBindingRegistered(boolean b){
  266. keyBindingRegistered = b;
  267. }
  268. public final boolean isKeyBindingActive(){
  269. return keyBindingActive;
  270. }
  271. protected final void setKeyBindingActive(boolean b){
  272. keyBindingActive = b;
  273. }
  274. protected void setupMenuOpenKey(){
  275. // PENDING(hania): Why are these WHEN_IN_FOCUSED_WINDOWs? Shouldn't
  276. // they be WHEN_ANCESTOR_OF_FOCUSED_COMPONENT?
  277. // Also, no longer registering on the desktopicon, the previous
  278. // action did nothing.
  279. InputMap map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
  280. SwingUtilities.replaceUIInputMap(frame,
  281. JComponent.WHEN_IN_FOCUSED_WINDOW, map);
  282. ActionMap actionMap = getActionMap();
  283. SwingUtilities.replaceUIActionMap(frame, actionMap);
  284. }
  285. protected void setupMenuCloseKey(){
  286. }
  287. public JComponent getNorthPane() {
  288. return northPane;
  289. }
  290. public void setNorthPane(JComponent c) {
  291. replacePane(northPane, c);
  292. northPane = c;
  293. }
  294. public JComponent getSouthPane() {
  295. return southPane;
  296. }
  297. public void setSouthPane(JComponent c) {
  298. // replacePane(southPane, c);
  299. southPane = c;
  300. }
  301. public JComponent getWestPane() {
  302. return westPane;
  303. }
  304. public void setWestPane(JComponent c) {
  305. // replacePane(westPane, c);
  306. westPane = c;
  307. }
  308. public JComponent getEastPane() {
  309. return eastPane;
  310. }
  311. public void setEastPane(JComponent c) {
  312. // replacePane(eastPane, c);
  313. eastPane = c;
  314. }
  315. public class InternalFramePropertyChangeListener implements PropertyChangeListener
  316. {
  317. /** Detects changes in state from the JInternalFrame and handles actions.*/
  318. public void propertyChange(PropertyChangeEvent evt) {
  319. String prop = (String)evt.getPropertyName();
  320. JInternalFrame f = (JInternalFrame)evt.getSource();
  321. Object newValue = evt.getNewValue();
  322. Object oldValue = evt.getOldValue();
  323. // ASSERT(frame == f) - This should always be true
  324. if(JInternalFrame.ROOT_PANE_PROPERTY.equals(prop)) {
  325. if(oldValue != null)
  326. frame.remove((Component)oldValue);
  327. if(newValue != null)
  328. frame.add((Component)newValue);
  329. /// Handle the action events from the Frame
  330. } else if(JInternalFrame.IS_CLOSED_PROPERTY.equals(prop)) {
  331. if(newValue == Boolean.TRUE){
  332. if ((frame.getParent() != null) && componentListenerAdded) {
  333. frame.getParent().removeComponentListener(componentListener);
  334. }
  335. closeFrame(f);
  336. }
  337. } else if(JInternalFrame.IS_MAXIMUM_PROPERTY.equals(prop)) {
  338. if(newValue == Boolean.TRUE)
  339. {
  340. maximizeFrame(f);
  341. }
  342. else
  343. {
  344. minimizeFrame(f);
  345. }
  346. } else if(JInternalFrame.IS_ICON_PROPERTY.equals(prop)) {
  347. if (newValue == Boolean.TRUE) {
  348. iconifyFrame(f);
  349. }
  350. else{
  351. deiconifyFrame(f);
  352. }
  353. } else if(JInternalFrame.IS_SELECTED_PROPERTY.equals(prop)) {
  354. Component glassPane = f.getGlassPane();
  355. if(newValue == Boolean.TRUE
  356. && oldValue == Boolean.FALSE) {
  357. activateFrame(f);
  358. // glassPane.removeMouseListener(glassPaneDispatcher);
  359. // glassPane.removeMouseMotionListener(glassPaneDispatcher);
  360. glassPane.setVisible(false);
  361. } else if(newValue == Boolean.FALSE
  362. && oldValue == Boolean.TRUE) {
  363. deactivateFrame(f);
  364. // glassPane.addMouseListener(glassPaneDispatcher);
  365. // glassPane.addMouseMotionListener(glassPaneDispatcher);
  366. glassPane.setVisible(true);
  367. }
  368. } else if ( prop.equals("ancestor") ) {
  369. if ((frame.getParent() != null) && !componentListenerAdded ) {
  370. f.getParent().addComponentListener(componentListener);
  371. componentListenerAdded = true;
  372. parentBounds = f.getParent().getBounds();
  373. }
  374. }
  375. }
  376. }
  377. public class InternalFrameLayout implements LayoutManager {
  378. public void addLayoutComponent(String name, Component c) {}
  379. public void removeLayoutComponent(Component c) {}
  380. public Dimension preferredLayoutSize(Container c) {
  381. Dimension result;
  382. Insets i = frame.getInsets();
  383. result = frame.getRootPane().getPreferredSize();
  384. result.width += i.left + i.right;
  385. result.height += i.top + i.bottom;
  386. if(getNorthPane() != null) {
  387. Dimension d = getNorthPane().getPreferredSize();
  388. result.width = Math.max(d.width, result.width);
  389. result.height += d.height;
  390. }
  391. if(getSouthPane() != null) {
  392. Dimension d = getSouthPane().getPreferredSize();
  393. result.width = Math.max(d.width, result.width);
  394. result.height += d.height;
  395. }
  396. if(getEastPane() != null) {
  397. Dimension d = getEastPane().getPreferredSize();
  398. result.width += d.width;
  399. result.height = Math.max(d.height, result.height);
  400. }
  401. if(getWestPane() != null) {
  402. Dimension d = getWestPane().getPreferredSize();
  403. result.width += d.width;
  404. result.height = Math.max(d.height, result.height);
  405. }
  406. return result;
  407. }
  408. public Dimension minimumLayoutSize(Container c) {
  409. Dimension result;
  410. Insets i = frame.getInsets();
  411. result = frame.getRootPane().getMinimumSize();
  412. result.width += i.left + i.right;
  413. result.height += i.top + i.bottom;
  414. if(getNorthPane() != null) {
  415. Dimension d = getNorthPane().getMinimumSize();
  416. result.width = Math.max(d.width, result.width);
  417. result.height += d.height;
  418. }
  419. if(getSouthPane() != null) {
  420. Dimension d = getSouthPane().getMinimumSize();
  421. result.width = Math.max(d.width, result.width);
  422. result.height += d.height;
  423. }
  424. if(getEastPane() != null) {
  425. Dimension d = getEastPane().getMinimumSize();
  426. result.width += d.width;
  427. result.height = Math.max(d.height, result.height);
  428. }
  429. if(getWestPane() != null) {
  430. Dimension d = getWestPane().getMinimumSize();
  431. result.width += d.width;
  432. result.height = Math.max(d.height, result.height);
  433. }
  434. return result;
  435. }
  436. public void layoutContainer(Container c) {
  437. Insets i = frame.getInsets();
  438. int cx, cy, cw, ch;
  439. cx = i.left;
  440. cy = i.top;
  441. cw = frame.getWidth() - i.left - i.right;
  442. ch = frame.getHeight() - i.top - i.bottom;
  443. if(getNorthPane() != null) {
  444. Dimension size = getNorthPane().getPreferredSize();
  445. getNorthPane().setBounds(cx, cy, cw, size.height);
  446. cy += size.height;
  447. ch -= size.height;
  448. }
  449. if(getSouthPane() != null) {
  450. Dimension size = getSouthPane().getPreferredSize();
  451. getSouthPane().setBounds(cx, frame.getHeight()
  452. - i.bottom - size.height,
  453. cw, size.height);
  454. ch -= size.height;
  455. }
  456. if(getWestPane() != null) {
  457. Dimension size = getWestPane().getPreferredSize();
  458. getWestPane().setBounds(cx, cy, size.width, ch);
  459. cw -= size.width;
  460. cx += size.width;
  461. }
  462. if(getEastPane() != null) {
  463. Dimension size = getEastPane().getPreferredSize();
  464. getEastPane().setBounds(cw - size.width, cy, size.width, ch);
  465. cw -= size.width;
  466. }
  467. if(frame.getRootPane() != null) {
  468. frame.getRootPane().setBounds(cx, cy, cw, ch);
  469. }
  470. }
  471. }
  472. /// DesktopManager methods
  473. /** Returns the proper DesktopManager. Calls getDesktopPane() to
  474. * find the JDesktop component and returns the desktopManager from
  475. * it. If this fails, it will return a default DesktopManager that
  476. * should work in arbitrary parents.
  477. */
  478. protected DesktopManager getDesktopManager() {
  479. if(frame.getDesktopPane() != null
  480. && frame.getDesktopPane().getDesktopManager() != null)
  481. return frame.getDesktopPane().getDesktopManager();
  482. if(sharedDesktopManager == null)
  483. sharedDesktopManager = createDesktopManager();
  484. return sharedDesktopManager;
  485. }
  486. protected DesktopManager createDesktopManager(){
  487. return new DefaultDesktopManager();
  488. }
  489. /** This method is called when the user wants to close the frame.
  490. * This action is delegated to the desktopManager.
  491. */
  492. protected void closeFrame(JInternalFrame f) {
  493. getDesktopManager().closeFrame(f);
  494. }
  495. /** This method is called when the user wants to maximize the frame.
  496. * This action is delegated to the desktopManager.
  497. */
  498. protected void maximizeFrame(JInternalFrame f) {
  499. getDesktopManager().maximizeFrame(f);
  500. }
  501. /** This method is called when the user wants to minimize the frame.
  502. * This action is delegated to the desktopManager.
  503. */
  504. protected void minimizeFrame(JInternalFrame f) {
  505. getDesktopManager().minimizeFrame(f);
  506. }
  507. /** This method is called when the user wants to iconify the frame.
  508. * This action is delegated to the desktopManager.
  509. */
  510. protected void iconifyFrame(JInternalFrame f) {
  511. getDesktopManager().iconifyFrame(f);
  512. }
  513. /** This method is called when the user wants to deiconify the frame.
  514. * This action is delegated to the desktopManager.
  515. */
  516. protected void deiconifyFrame(JInternalFrame f) {
  517. getDesktopManager().deiconifyFrame(f);
  518. }
  519. /** This method is called when the frame becomes selected.
  520. * This action is delegated to the desktopManager.
  521. */
  522. protected void activateFrame(JInternalFrame f) {
  523. getDesktopManager().activateFrame(f);
  524. }
  525. /** This method is called when the frame is no longer selected.
  526. * This action is delegated to the desktopManager.
  527. */
  528. protected void deactivateFrame(JInternalFrame f) {
  529. getDesktopManager().deactivateFrame(f);
  530. }
  531. /////////////////////////////////////////////////////////////////////////
  532. /// Border Listener Class
  533. /////////////////////////////////////////////////////////////////////////
  534. /**
  535. * Listens for border adjustments.
  536. */
  537. protected class BorderListener extends MouseInputAdapter implements SwingConstants
  538. {
  539. // _x & _y are the mousePressed location in absolute coordinate system
  540. int _x, _y;
  541. // __x & __y are the mousePressed location in source view's coordinate system
  542. int __x, __y;
  543. Rectangle startingBounds;
  544. int resizeDir;
  545. protected final int RESIZE_NONE = 0;
  546. int resizeCornerSize = 16;
  547. public void mouseClicked(MouseEvent e) {
  548. if(e.getClickCount() > 1 && e.getSource() == getNorthPane()) {
  549. if(frame.isIconifiable() && frame.isIcon()) {
  550. try { frame.setIcon(false); } catch (PropertyVetoException e2) { }
  551. } else if(frame.isMaximizable()) {
  552. if(!frame.isMaximum())
  553. try { frame.setMaximum(true); } catch (PropertyVetoException e2) { }
  554. else
  555. try { frame.setMaximum(false); } catch (PropertyVetoException e3) { }
  556. }
  557. }
  558. }
  559. public void mouseReleased(MouseEvent e) {
  560. if(resizeDir == RESIZE_NONE)
  561. getDesktopManager().endDraggingFrame(frame);
  562. else
  563. getDesktopManager().endResizingFrame(frame);
  564. _x = 0;
  565. _y = 0;
  566. __x = 0;
  567. __y = 0;
  568. startingBounds = null;
  569. resizeDir = RESIZE_NONE;
  570. }
  571. public void mousePressed(MouseEvent e) {
  572. Point p = SwingUtilities.convertPoint((Component)e.getSource(),
  573. e.getX(), e.getY(), null);
  574. __x = e.getX();
  575. __y = e.getY();
  576. _x = p.x;
  577. _y = p.y;
  578. startingBounds = frame.getBounds();
  579. if(!frame.isSelected()) {
  580. try { frame.setSelected(true); } catch (PropertyVetoException e1) { }
  581. }
  582. if(!frame.isResizable() || e.getSource() == getNorthPane()) {
  583. resizeDir = RESIZE_NONE;
  584. getDesktopManager().beginDraggingFrame(frame);
  585. return;
  586. }
  587. if(e.getSource() == frame) {
  588. Insets i = frame.getInsets();
  589. if(e.getX() <= i.left) {
  590. if(e.getY() < resizeCornerSize + i.top)
  591. resizeDir = NORTH_WEST;
  592. else if(e.getY() > frame.getHeight()
  593. - resizeCornerSize - i.bottom)
  594. resizeDir = SOUTH_WEST;
  595. else
  596. resizeDir = WEST;
  597. } else if(e.getX() >= frame.getWidth() - i.right) {
  598. if(e.getY() < resizeCornerSize + i.top)
  599. resizeDir = NORTH_EAST;
  600. else if(e.getY() > frame.getHeight()
  601. - resizeCornerSize - i.bottom)
  602. resizeDir = SOUTH_EAST;
  603. else
  604. resizeDir = EAST;
  605. } else if(e.getY() <= i.top) {
  606. if(e.getX() < resizeCornerSize + i.left)
  607. resizeDir = NORTH_WEST;
  608. else if(e.getX() > frame.getWidth()
  609. - resizeCornerSize - i.right)
  610. resizeDir = NORTH_EAST;
  611. else
  612. resizeDir = NORTH;
  613. } else if(e.getY() >= frame.getHeight() - i.bottom) {
  614. if(e.getX() < resizeCornerSize + i.left)
  615. resizeDir = SOUTH_WEST;
  616. else if(e.getX() > frame.getWidth()
  617. - resizeCornerSize - i.right)
  618. resizeDir = SOUTH_EAST;
  619. else
  620. resizeDir = SOUTH;
  621. }
  622. getDesktopManager().beginResizingFrame(frame, resizeDir);
  623. return;
  624. }
  625. }
  626. public void mouseDragged(MouseEvent e) {
  627. if ( startingBounds == null ) {
  628. // (STEVE) Yucky work around for bug ID 4106552
  629. return;
  630. }
  631. Point p;
  632. int newX, newY, newW, newH;
  633. int deltaX;
  634. int deltaY;
  635. Dimension min;
  636. Dimension max;
  637. p = SwingUtilities.convertPoint((Component)e.getSource(),
  638. e.getX(), e.getY(), null);
  639. // Handle a MOVE
  640. if(e.getSource() == getNorthPane()) {
  641. if (frame.isMaximum()) {
  642. return; // don't allow moving of maximized frames.
  643. }
  644. Insets i = frame.getInsets();
  645. int pWidth, pHeight;
  646. Dimension s = frame.getParent().getSize();
  647. pWidth = s.width;
  648. pHeight = s.height;
  649. newX = startingBounds.x - (_x - p.x);
  650. newY = startingBounds.y - (_y - p.y);
  651. // Make sure we stay in-bounds
  652. if(newX + i.left <= -__x)
  653. newX = -__x - i.left;
  654. if(newY + i.top <= -__y)
  655. newY = -__y - i.top;
  656. if(newX + __x + i.right > pWidth)
  657. newX = pWidth - __x - i.right;
  658. if(newY + __y + i.bottom > pHeight)
  659. newY = pHeight - __y - i.bottom;
  660. getDesktopManager().dragFrame(frame, newX, newY);
  661. return;
  662. }
  663. if(!frame.isResizable()) {
  664. return;
  665. }
  666. min = frame.getMinimumSize();
  667. max = frame.getMaximumSize();
  668. deltaX = _x - p.x;
  669. deltaY = _y - p.y;
  670. newX = frame.getX();
  671. newY = frame.getY();
  672. newW = frame.getWidth();
  673. newH = frame.getHeight();
  674. switch(resizeDir) {
  675. case RESIZE_NONE:
  676. return;
  677. case NORTH:
  678. if(startingBounds.height + deltaY < min.height)
  679. deltaY = -(startingBounds.height - min.height);
  680. else if(startingBounds.height + deltaY > max.height)
  681. deltaY = max.height - startingBounds.height;
  682. if (startingBounds.y - deltaY < 0) {deltaY = startingBounds.y;}
  683. newY = startingBounds.y - deltaY;
  684. newX = startingBounds.x;
  685. newW = startingBounds.width;
  686. newH = startingBounds.height + deltaY;
  687. break;
  688. case NORTH_EAST:
  689. if(startingBounds.height + deltaY < min.height)
  690. deltaY = -(startingBounds.height - min.height);
  691. else if(startingBounds.height + deltaY > max.height)
  692. deltaY = max.height - startingBounds.height;
  693. if (startingBounds.y - deltaY < 0) {deltaY = startingBounds.y;}
  694. if(startingBounds.width - deltaX < min.width)
  695. deltaX = startingBounds.width - min.width;
  696. else if(startingBounds.width - deltaX > max.width)
  697. deltaX = -(max.width - startingBounds.width);
  698. if (startingBounds.x + startingBounds.width - deltaX > parentBounds.width) {
  699. deltaX = startingBounds.x + startingBounds.width - parentBounds.width;
  700. }
  701. newX = startingBounds.x;
  702. newY = startingBounds.y - deltaY;
  703. newW = startingBounds.width - deltaX;
  704. newH = startingBounds.height + deltaY;
  705. break;
  706. case EAST:
  707. if(startingBounds.width - deltaX < min.width)
  708. deltaX = startingBounds.width - min.width;
  709. else if(startingBounds.width - deltaX > max.width)
  710. deltaX = -(max.width - startingBounds.width);
  711. if (startingBounds.x + startingBounds.width - deltaX > parentBounds.width) {
  712. deltaX = startingBounds.x + startingBounds.width - parentBounds.width;
  713. }
  714. newW = startingBounds.width - deltaX;
  715. newH = startingBounds.height;
  716. break;
  717. case SOUTH_EAST:
  718. if(startingBounds.width - deltaX < min.width)
  719. deltaX = startingBounds.width - min.width;
  720. else if(startingBounds.width - deltaX > max.width)
  721. deltaX = -(max.width - startingBounds.width);
  722. if (startingBounds.x + startingBounds.width - deltaX > parentBounds.width) {
  723. deltaX = startingBounds.x + startingBounds.width - parentBounds.width;
  724. }
  725. if(startingBounds.height - deltaY < min.height)
  726. deltaY = startingBounds.height - min.height;
  727. else if(startingBounds.height - deltaY > max.height)
  728. deltaY = -(max.height - startingBounds.height);
  729. if (startingBounds.y + startingBounds.height - deltaY > parentBounds.height) {
  730. deltaY = startingBounds.y + startingBounds.height - parentBounds.height ;
  731. }
  732. newW = startingBounds.width - deltaX;
  733. newH = startingBounds.height - deltaY;
  734. break;
  735. case SOUTH:
  736. if(startingBounds.height - deltaY < min.height)
  737. deltaY = (startingBounds.height - min.height);
  738. else if(startingBounds.height - deltaY > max.height)
  739. deltaY = -(max.height - startingBounds.height);
  740. if (startingBounds.y + startingBounds.height - deltaY > parentBounds.height) {
  741. deltaY = startingBounds.y + startingBounds.height - parentBounds.height ;
  742. }
  743. newW = startingBounds.width;
  744. newH = startingBounds.height - deltaY;
  745. break;
  746. case SOUTH_WEST:
  747. if(startingBounds.height - deltaY < min.height)
  748. deltaY = (startingBounds.height - min.height);
  749. else if(startingBounds.height - deltaY > max.height)
  750. deltaY = -(max.height - startingBounds.height);
  751. if (startingBounds.y + startingBounds.height - deltaY > parentBounds.height) {
  752. deltaY = startingBounds.y + startingBounds.height - parentBounds.height ;
  753. }
  754. if(startingBounds.width + deltaX < min.width)
  755. deltaX = -(startingBounds.width - min.width);
  756. else if(startingBounds.width + deltaX > max.width)
  757. deltaX = max.width - startingBounds.width;
  758. if (startingBounds.x - deltaX < 0) {
  759. deltaX = startingBounds.x;
  760. }
  761. newX = startingBounds.x - deltaX;
  762. newY = startingBounds.y;
  763. newW = startingBounds.width + deltaX;
  764. newH = startingBounds.height - deltaY;
  765. break;
  766. case WEST:
  767. if(startingBounds.width + deltaX < min.width)
  768. deltaX = -(startingBounds.width - min.width);
  769. else if(startingBounds.width + deltaX > max.width)
  770. deltaX = max.width - startingBounds.width;
  771. if (startingBounds.x - deltaX < 0) {
  772. deltaX = startingBounds.x;
  773. }
  774. newX = startingBounds.x - deltaX;
  775. newY = startingBounds.y;
  776. newW = startingBounds.width + deltaX;
  777. newH = startingBounds.height;
  778. break;
  779. case NORTH_WEST:
  780. if(startingBounds.width + deltaX < min.width)
  781. deltaX = -(startingBounds.width - min.width);
  782. else if(startingBounds.width + deltaX > max.width)
  783. deltaX = max.width - startingBounds.width;
  784. if (startingBounds.x - deltaX < 0) {
  785. deltaX = startingBounds.x;
  786. }
  787. if(startingBounds.height + deltaY < min.height)
  788. deltaY = -(startingBounds.height - min.height);
  789. else if(startingBounds.height + deltaY > max.height)
  790. deltaY = max.height - startingBounds.height;
  791. if (startingBounds.y - deltaY < 0) {deltaY = startingBounds.y;}
  792. newX = startingBounds.x - deltaX;
  793. newY = startingBounds.y - deltaY;
  794. newW = startingBounds.width + deltaX;
  795. newH = startingBounds.height + deltaY;
  796. break;
  797. default:
  798. return;
  799. }
  800. getDesktopManager().resizeFrame(frame, newX, newY, newW, newH);
  801. }
  802. public void mouseMoved(MouseEvent e) {
  803. if(!frame.isResizable())
  804. return;
  805. if(e.getSource() == frame) {
  806. Insets i = frame.getInsets();
  807. if(e.getX() <= i.left) {
  808. if(e.getY() < resizeCornerSize + i.top)
  809. frame.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
  810. else if(e.getY() > frame.getHeight() - resizeCornerSize - i.bottom)
  811. frame.setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
  812. else
  813. frame.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
  814. } else if(e.getX() >= frame.getWidth() - i.right) {
  815. if(e.getY() < resizeCornerSize + i.top)
  816. frame.setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
  817. else if(e.getY() > frame.getHeight() - resizeCornerSize - i.bottom)
  818. frame.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
  819. else
  820. frame.setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
  821. } else if(e.getY() <= i.top) {
  822. if(e.getX() < resizeCornerSize + i.left)
  823. frame.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
  824. else if(e.getX() > frame.getWidth() - resizeCornerSize - i.right)
  825. frame.setCursor(Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
  826. else
  827. frame.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
  828. } else if(e.getY() >= frame.getHeight() - i.bottom) {
  829. if(e.getX() < resizeCornerSize + i.left)
  830. frame.setCursor(Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
  831. else if(e.getX() > frame.getWidth() - resizeCornerSize - i.right)
  832. frame.setCursor(Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
  833. else
  834. frame.setCursor(Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
  835. }
  836. return;
  837. }
  838. frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  839. }
  840. public void mouseExited(MouseEvent e) {
  841. frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  842. }
  843. }; /// End BorderListener Class
  844. protected class ComponentHandler implements ComponentListener
  845. {
  846. /**
  847. * Invoked when a JInternalFrame's parent's size changes.
  848. */
  849. public void componentResized(ComponentEvent e) {
  850. //
  851. // Get the JInternalFrame's parent container size
  852. //
  853. Rectangle parentNewBounds = ((Component) e.getSource()).getBounds();
  854. JInternalFrame.JDesktopIcon icon = null;
  855. if (frame != null) {
  856. icon = frame.getDesktopIcon();
  857. //
  858. // Resize the internal frame if it is maximized and relocate
  859. // the associated icon as well.
  860. //
  861. if ( frame.isMaximum() ) {
  862. frame.setBounds(0, 0, parentNewBounds.width, parentNewBounds.height);
  863. }
  864. }
  865. //
  866. // Relocate the icon base on the new parent bounds.
  867. //
  868. if (icon != null) {
  869. Rectangle iconBounds = icon.getBounds();
  870. int y = iconBounds.y + (parentNewBounds.height - parentBounds.height);
  871. icon.setBounds(iconBounds.x,y,iconBounds.width,iconBounds.height);
  872. }
  873. //
  874. // Update the new parent bounds for next resize.
  875. //
  876. if ( !parentBounds.equals(parentNewBounds) ) {
  877. parentBounds = parentNewBounds;
  878. }
  879. //
  880. // Validate the component tree for this container.
  881. //
  882. if (frame != null) frame.validate();
  883. }
  884. /* Unused */
  885. public void componentMoved(ComponentEvent e) {}
  886. /* Unused */
  887. public void componentShown(ComponentEvent e) {}
  888. /* Unused */
  889. public void componentHidden(ComponentEvent e) {}
  890. }
  891. protected ComponentListener createComponentListener()
  892. {
  893. return new ComponentHandler();
  894. }
  895. protected class GlassPaneDispatcher implements MouseInputListener
  896. {
  897. /**
  898. * When inactive, mouse events are forwarded as appropriate either to
  899. * the UI to activate the frame or to the underlying child component.
  900. *
  901. * In keeping with the MDI messaging model (which JInternalFrame
  902. * emulates), only the mousePressed event is forwarded to the UI
  903. * to activate the frame. The mouseEntered, mouseMoved, and
  904. * MouseExited events are forwarded to the underlying child
  905. * component, using methods derived from those in Container.
  906. * The other mouse events are purposely ignored, since they have
  907. * no meaning to either the frame or its children when the frame
  908. * is inactive.
  909. */
  910. public void mousePressed(MouseEvent e) {
  911. // what is going on here is the GlassPane is up on the inactive
  912. // internalframe and want's to "catch" the first mousePressed on
  913. // the frame in order to give it to the BorderLister (and not the
  914. // underlying component) and let it activate the frame
  915. if (borderListener != null){
  916. borderListener.mousePressed(e);
  917. }
  918. // fix for 4152560
  919. forwardMouseEvent(e);
  920. }
  921. /**
  922. * Forward the mouseEntered event to the underlying child container.
  923. * @see #mousePressed
  924. */
  925. public void mouseEntered(MouseEvent e) {
  926. forwardMouseEvent(e);
  927. }
  928. /**
  929. * Forward the mouseMoved event to the underlying child container.
  930. * @see #mousePressed
  931. */
  932. public void mouseMoved(MouseEvent e) {
  933. forwardMouseEvent(e);
  934. }
  935. /**
  936. * Forward the mouseExited event to the underlying child container.
  937. * @see #mousePressed
  938. */
  939. public void mouseExited(MouseEvent e) {
  940. forwardMouseEvent(e);
  941. }
  942. /**
  943. * Ignore mouseClicked events.
  944. * @see #mousePressed
  945. */
  946. public void mouseClicked(MouseEvent e) {
  947. }
  948. /**
  949. * Ignore mouseReleased events.
  950. * @see #mousePressed
  951. */
  952. public void mouseReleased(MouseEvent e) {
  953. //System.out.println("forward release");
  954. forwardMouseEvent(e);
  955. }
  956. /**
  957. * Ignore mouseDragged events.
  958. * @see #mousePressed
  959. */
  960. public void mouseDragged(MouseEvent e) {
  961. }
  962. /*
  963. * Forward a mouse event to the current mouse target, setting it
  964. * if necessary.
  965. */
  966. private void forwardMouseEvent(MouseEvent e) {
  967. Component target = findComponentAt(frame.getRootPane().getLayeredPane(),
  968. e.getX(), e.getY());
  969. //if (e.getID() == MouseEvent.MOUSE_PRESSED) {
  970. // System.out.println("Mouse pressed forwarded to " + target);
  971. //} else if (e.getID() == MouseEvent.MOUSE_RELEASED) {
  972. //System.out.println("Mouse released forwarded to " + target);
  973. //} else if (e.getID() == MouseEvent.MOUSE_CLICKED) {
  974. //System.out.println("Mouse clicked forwarded to " + target);
  975. //}
  976. if (target != mouseEventTarget) {
  977. setMouseTarget(target, e);
  978. }
  979. retargetMouseEvent(e.getID(), e);
  980. }
  981. private Component mouseEventTarget = null;
  982. /*
  983. * Find the lightweight child component which corresponds to the
  984. * specified location. This is similar to the new 1.2 API in
  985. * Container, but we need to run on 1.1. The other changes are
  986. * due to Container.findComponentAt's use of package-private data.
  987. */
  988. private Component findComponentAt(Container c, int x, int y) {
  989. if (!c.contains(x, y)) {
  990. return c;
  991. }
  992. int ncomponents = c.getComponentCount();
  993. Component component[] = c.getComponents();
  994. for (int i = 0 ; i < ncomponents ; i++) {
  995. Component comp = component[i];
  996. Point loc = comp.getLocation();
  997. if ((comp != null) && (comp.contains(x - loc.x, y - loc.y)) &&
  998. (comp.getPeer() instanceof java.awt.peer.LightweightPeer) &&
  999. (comp.isVisible() == true)) {
  1000. // found a component that intersects the point, see if there
  1001. // is a deeper possibility.
  1002. if (comp instanceof Container) {
  1003. Container child = (Container) comp;
  1004. Point childLoc = child.getLocation();
  1005. Component deeper = findComponentAt(child,
  1006. x - childLoc.x, y - childLoc.y);
  1007. if (deeper != null) {
  1008. return deeper;
  1009. }
  1010. } else {
  1011. return comp;
  1012. }
  1013. }
  1014. }
  1015. return c;
  1016. }
  1017. /*
  1018. * Set the child component to which events are forwarded, and
  1019. * synthesize the appropriate mouseEntered and mouseExited events.
  1020. */
  1021. private void setMouseTarget(Component target, MouseEvent e) {
  1022. if (mouseEventTarget != null) {
  1023. retargetMouseEvent(MouseEvent.MOUSE_EXITED, e);
  1024. }
  1025. mouseEventTarget = target;
  1026. if (mouseEventTarget != null) {
  1027. retargetMouseEvent(MouseEvent.MOUSE_ENTERED, e);
  1028. }
  1029. }
  1030. /*
  1031. * Dispatch an event clone, retargeted for the current mouse target.
  1032. */
  1033. void retargetMouseEvent(int id, MouseEvent e) {
  1034. // fix for bug #4202966 -- hania
  1035. // When retargetting a mouse event, we need to translate
  1036. // the event's coordinates relative to the target.
  1037. Point p = SwingUtilities.convertPoint(frame.getLayeredPane(),
  1038. e.getX(), e.getY(),
  1039. mouseEventTarget);
  1040. MouseEvent retargeted = new MouseEvent(mouseEventTarget,
  1041. id,
  1042. e.getWhen(),
  1043. e.getModifiers(),
  1044. p.x,
  1045. p.y,
  1046. e.getClickCount(),
  1047. e.isPopupTrigger());
  1048. mouseEventTarget.dispatchEvent(retargeted);
  1049. }
  1050. }
  1051. protected MouseInputListener createGlassPaneDispatcher(){
  1052. return new GlassPaneDispatcher();
  1053. }
  1054. protected class BasicInternalFrameListener implements InternalFrameListener {
  1055. public void internalFrameClosing(InternalFrameEvent e) {
  1056. }
  1057. public void internalFrameClosed(InternalFrameEvent e) {
  1058. frame.removeInternalFrameListener(internalFrameListener);
  1059. }
  1060. public void internalFrameOpened(InternalFrameEvent e) {
  1061. }
  1062. public void internalFrameIconified(InternalFrameEvent e) {
  1063. }
  1064. public void internalFrameDeiconified(InternalFrameEvent e) {
  1065. }
  1066. public void internalFrameActivated(InternalFrameEvent e) {
  1067. if (!isKeyBindingRegistered()){
  1068. setKeyBindingRegistered(true);
  1069. setupMenuOpenKey();
  1070. setupMenuCloseKey();
  1071. }
  1072. if (isKeyBindingRegistered())
  1073. setKeyBindingActive(true);
  1074. }
  1075. public void internalFrameDeactivated(InternalFrameEvent e) {
  1076. setKeyBindingActive(false);
  1077. }
  1078. }
  1079. } /// End BasicInternalFrameUI Class