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