Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / javax / swing / plaf / basic / BasicInternalFrameUI.java
blobf6cbeec88796fe7eeb059b605253795c8d1c2b7f
1 /* BasicInternalFrameUI.java --
2 Copyright (C) 2004, 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package javax.swing.plaf.basic;
41 import java.awt.AWTEvent;
42 import java.awt.Color;
43 import java.awt.Component;
44 import java.awt.Container;
45 import java.awt.Dimension;
46 import java.awt.Graphics;
47 import java.awt.Insets;
48 import java.awt.LayoutManager;
49 import java.awt.LayoutManager2;
50 import java.awt.Point;
51 import java.awt.Rectangle;
52 import java.awt.event.ComponentEvent;
53 import java.awt.event.ComponentListener;
54 import java.awt.event.MouseEvent;
55 import java.beans.PropertyChangeEvent;
56 import java.beans.PropertyChangeListener;
58 import javax.swing.DefaultDesktopManager;
59 import javax.swing.DesktopManager;
60 import javax.swing.JComponent;
61 import javax.swing.JDesktopPane;
62 import javax.swing.JInternalFrame;
63 import javax.swing.KeyStroke;
64 import javax.swing.LookAndFeel;
65 import javax.swing.SwingConstants;
66 import javax.swing.SwingUtilities;
67 import javax.swing.UIManager;
68 import javax.swing.border.AbstractBorder;
69 import javax.swing.event.InternalFrameEvent;
70 import javax.swing.event.InternalFrameListener;
71 import javax.swing.event.MouseInputAdapter;
72 import javax.swing.event.MouseInputListener;
73 import javax.swing.plaf.ComponentUI;
74 import javax.swing.plaf.InternalFrameUI;
75 import javax.swing.plaf.UIResource;
77 /**
78 * This is the UI delegate for the Basic look and feel for JInternalFrames.
80 public class BasicInternalFrameUI extends InternalFrameUI
82 /**
83 * This is a helper class that listens to the JInternalFrame for
84 * InternalFrameEvents.
86 protected class BasicInternalFrameListener implements InternalFrameListener
88 /**
89 * This method is called when the JInternalFrame is activated.
91 * @param e The InternalFrameEvent.
93 public void internalFrameActivated(InternalFrameEvent e)
95 frame.getGlassPane().setVisible(false);
98 /**
99 * This method is called when the JInternalFrame is closed.
101 * @param e The InternalFrameEvent.
103 public void internalFrameClosed(InternalFrameEvent e)
105 // FIXME: Implement.
109 * This method is called when the JInternalFrame is closing.
111 * @param e The InternalFrameEvent.
113 public void internalFrameClosing(InternalFrameEvent e)
115 // FIXME: Implement.
119 * This method is called when the JInternalFrame is deactivated.
121 * @param e The InternalFrameEvent.
123 public void internalFrameDeactivated(InternalFrameEvent e)
125 frame.getGlassPane().setVisible(true);
129 * This method is called when the JInternalFrame is deiconified.
131 * @param e The InternalFrameEvent.
133 public void internalFrameDeiconified(InternalFrameEvent e)
135 // FIXME: Implement.
139 * This method is called when the JInternalFrame is iconified.
141 * @param e The InternalFrameEvent.
143 public void internalFrameIconified(InternalFrameEvent e)
145 // FIXME: Implement.
149 * This method is called when the JInternalFrame is opened.
151 * @param e The InternalFrameEvent.
153 public void internalFrameOpened(InternalFrameEvent e)
155 // FIXME: Implement.
160 * This helper class listens to the edges of the JInternalFrame and the
161 * TitlePane for mouse events. It is responsible for dragging and resizing
162 * the JInternalFrame in response to the MouseEvents.
164 protected class BorderListener extends MouseInputAdapter
165 implements SwingConstants
167 /** FIXME: Use for something. */
168 protected final int RESIZE_NONE = 0;
170 /** The x offset from the top left corner of the JInternalFrame. */
171 private transient int xOffset = 0;
173 /** The y offset from the top left corner of the JInternalFrame. */
174 private transient int yOffset = 0;
176 /** The direction that the resize is occuring in. */
177 private transient int direction = -1;
179 /** Cache rectangle that can be reused. */
180 private transient Rectangle cacheRect = new Rectangle();
183 * This method is called when the mouse is clicked.
185 * @param e The MouseEvent.
187 public void mouseClicked(MouseEvent e)
189 // There is nothing to do when the mouse is clicked
190 // on the border.
194 * This method is called when the mouse is dragged. This method is
195 * responsible for resizing or dragging the JInternalFrame.
197 * @param e The MouseEvent.
199 public void mouseDragged(MouseEvent e)
201 // If the frame is maximized, there is nothing that
202 // can be dragged around.
203 if (frame.isMaximum())
204 return;
205 DesktopManager dm = getDesktopManager();
206 Rectangle b = frame.getBounds();
207 Dimension min = frame.getMinimumSize();
208 if (min == null)
209 min = new Dimension(0, 0);
210 Insets insets = frame.getInsets();
211 int x = e.getX();
212 int y = e.getY();
213 if (e.getSource() == frame && frame.isResizable())
215 switch (direction)
217 case NORTH:
218 cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height
219 - min.height),
220 b.width, b.height - y);
221 break;
222 case NORTH_EAST:
223 cacheRect.setBounds(b.x, Math.min(b.y + y, b.y + b.height
224 - min.height), x,
225 b.height - y);
226 break;
227 case EAST:
228 cacheRect.setBounds(b.x, b.y, x, b.height);
229 break;
230 case SOUTH_EAST:
231 cacheRect.setBounds(b.x, b.y, x, y);
232 break;
233 case SOUTH:
234 cacheRect.setBounds(b.x, b.y, b.width, y);
235 break;
236 case SOUTH_WEST:
237 cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
238 b.y, b.width - x, y);
239 break;
240 case WEST:
241 cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
242 b.y, b.width - x, b.height);
243 break;
244 case NORTH_WEST:
245 cacheRect.setBounds(
246 Math.min(b.x + x, b.x + b.width - min.width),
247 Math.min(b.y + y, b.y + b.height - min.height),
248 b.width - x, b.height - y);
249 break;
251 dm.resizeFrame(frame, cacheRect.x, cacheRect.y,
252 Math.max(min.width, cacheRect.width),
253 Math.max(min.height, cacheRect.height));
255 else if (e.getSource() == titlePane)
257 Rectangle fBounds = frame.getBounds();
259 dm.dragFrame(frame, e.getX() - xOffset + b.x, e.getY() - yOffset
260 + b.y);
265 * This method is called when the mouse exits the JInternalFrame.
267 * @param e The MouseEvent.
269 public void mouseExited(MouseEvent e)
271 // There is nothing to do when the mouse exits
272 // the border area.
276 * This method is called when the mouse is moved inside the
277 * JInternalFrame.
279 * @param e The MouseEvent.
281 public void mouseMoved(MouseEvent e)
283 // There is nothing to do when the mouse moves
284 // over the border area.
288 * This method is called when the mouse is pressed.
290 * @param e The MouseEvent.
292 public void mousePressed(MouseEvent e)
294 activateFrame(frame);
295 DesktopManager dm = getDesktopManager();
296 int x = e.getX();
297 int y = e.getY();
298 Insets insets = frame.getInsets();
300 if (e.getSource() == frame && frame.isResizable())
302 direction = sectionOfClick(x, y);
303 dm.beginResizingFrame(frame, direction);
305 else if (e.getSource() == titlePane)
307 Rectangle tBounds = titlePane.getBounds();
309 xOffset = e.getX() - tBounds.x + insets.left;
310 yOffset = e.getY() - tBounds.y + insets.top;
312 dm.beginDraggingFrame(frame);
317 * This method is called when the mouse is released.
319 * @param e The MouseEvent.
321 public void mouseReleased(MouseEvent e)
323 DesktopManager dm = getDesktopManager();
324 xOffset = 0;
325 yOffset = 0;
326 if (e.getSource() == frame && frame.isResizable())
327 dm.endResizingFrame(frame);
328 else if (e.getSource() == titlePane)
329 dm.endDraggingFrame(frame);
333 * This method determines the direction of the resize based on the
334 * coordinates and the size of the JInternalFrame.
336 * @param x The x coordinate of the MouseEvent.
337 * @param y The y coordinate of the MouseEvent.
339 * @return The direction of the resize (a SwingConstant direction).
341 private int sectionOfClick(int x, int y)
343 Insets insets = frame.getInsets();
344 Rectangle b = frame.getBounds();
345 if (x < insets.left && y < insets.top)
346 return NORTH_WEST;
347 else if (x > b.width - insets.right && y < insets.top)
348 return NORTH_EAST;
349 else if (x > b.width - insets.right && y > b.height - insets.bottom)
350 return SOUTH_EAST;
351 else if (x < insets.left && y > b.height - insets.bottom)
352 return SOUTH_WEST;
353 else if (y < insets.top)
354 return NORTH;
355 else if (x < insets.left)
356 return WEST;
357 else if (y > b.height - insets.bottom)
358 return SOUTH;
359 else if (x > b.width - insets.right)
360 return EAST;
362 return -1;
367 * This helper class listens to the JDesktopPane that parents this
368 * JInternalFrame and listens for resize events and resizes the
369 * JInternalFrame appropriately.
371 protected class ComponentHandler implements ComponentListener
374 * This method is called when the JDesktopPane is hidden.
376 * @param e
377 * The ComponentEvent fired.
379 public void componentHidden(ComponentEvent e)
381 // Do nothing.
385 * This method is called when the JDesktopPane is moved.
387 * @param e
388 * The ComponentEvent fired.
390 public void componentMoved(ComponentEvent e)
392 // Do nothing.
396 * This method is called when the JDesktopPane is resized.
398 * @param e
399 * The ComponentEvent fired.
401 public void componentResized(ComponentEvent e)
403 if (frame.isMaximum())
405 JDesktopPane pane = (JDesktopPane) e.getSource();
406 Insets insets = pane.getInsets();
407 Rectangle bounds = pane.getBounds();
409 frame.setBounds(bounds.x + insets.left, bounds.y + insets.top,
410 bounds.width - insets.left - insets.right,
411 bounds.height - insets.top - insets.bottom);
412 frame.revalidate();
413 frame.repaint();
416 // Sun also resizes the icons. but it doesn't seem to do anything.
420 * This method is called when the JDesktopPane is shown.
422 * @param e
423 * The ComponentEvent fired.
425 public void componentShown(ComponentEvent e)
427 // Do nothing.
432 * This helper class acts as the LayoutManager for JInternalFrames.
434 public class InternalFrameLayout implements LayoutManager
437 * This method is called when the given Component is added to the
438 * JInternalFrame.
440 * @param name
441 * The name of the Component.
442 * @param c
443 * The Component added.
445 public void addLayoutComponent(String name, Component c)
447 // Nothing to do here.
451 * This method is used to set the bounds of the children of the
452 * JInternalFrame.
454 * @param c
455 * The Container to lay out.
457 public void layoutContainer(Container c)
459 Dimension dims = frame.getSize();
460 Insets insets = frame.getInsets();
462 dims.width -= insets.left + insets.right;
463 dims.height -= insets.top + insets.bottom;
465 int nh = 0;
466 int sh = 0;
467 int ew = 0;
468 int ww = 0;
470 if (northPane != null)
472 Dimension nDims = northPane.getPreferredSize();
473 nh = Math.min(nDims.height, dims.height);
475 northPane.setBounds(insets.left, insets.top, dims.width, nh);
478 if (southPane != null)
480 Dimension sDims = southPane.getPreferredSize();
481 sh = Math.min(sDims.height, dims.height - nh);
483 southPane.setBounds(insets.left, insets.top + dims.height - sh,
484 dims.width, sh);
487 int remHeight = dims.height - sh - nh;
489 if (westPane != null)
491 Dimension wDims = westPane.getPreferredSize();
492 ww = Math.min(dims.width, wDims.width);
494 westPane.setBounds(insets.left, insets.top + nh, ww, remHeight);
497 if (eastPane != null)
499 Dimension eDims = eastPane.getPreferredSize();
500 ew = Math.min(eDims.width, dims.width - ww);
502 eastPane.setBounds(insets.left + dims.width - ew, insets.top + nh,
503 ew, remHeight);
506 int remWidth = dims.width - ww - ew;
508 frame.getRootPane().setBounds(insets.left + ww, insets.top + nh,
509 remWidth, remHeight);
513 * This method returns the minimum layout size.
515 * @param c
516 * The Container to find a minimum layout size for.
517 * @return The minimum dimensions for the JInternalFrame.
519 public Dimension minimumLayoutSize(Container c)
521 return getSize(c, true);
525 * Th8is method returns the preferred layout size.
527 * @param c
528 * The Container to find a preferred layout size for.
529 * @return The preferred dimensions for the JInternalFrame.
531 public Dimension preferredLayoutSize(Container c)
533 return getSize(c, false);
537 * DOCUMENT ME!
539 * @param c
540 * DOCUMENT ME!
541 * @param min
542 * DOCUMENT ME!
543 * @return DOCUMENT ME!
545 private Dimension getSize(Container c, boolean min)
547 Insets insets = frame.getInsets();
549 Dimension contentDims = frame.getContentPane().getPreferredSize();
550 if (min)
551 contentDims.width = contentDims.height = 0;
552 int nWidth = 0;
553 int nHeight = 0;
554 int sWidth = 0;
555 int sHeight = 0;
556 int eWidth = 0;
557 int eHeight = 0;
558 int wWidth = 0;
559 int wHeight = 0;
560 Dimension dims;
562 if (northPane != null)
564 dims = northPane.getPreferredSize();
565 if (dims != null)
567 nWidth = dims.width;
568 nHeight = dims.height;
572 if (southPane != null)
574 dims = southPane.getPreferredSize();
575 if (dims != null)
577 sWidth = dims.width;
578 sHeight = dims.height;
582 if (eastPane != null)
584 dims = eastPane.getPreferredSize();
585 if (dims != null)
587 sWidth = dims.width;
588 sHeight = dims.height;
592 if (westPane != null)
594 dims = westPane.getPreferredSize();
595 if (dims != null)
597 wWidth = dims.width;
598 wHeight = dims.height;
602 int width = Math.max(sWidth, nWidth);
603 width = Math.max(width, contentDims.width + eWidth + wWidth);
605 int height = Math.max(eHeight, wHeight);
606 height = Math.max(height, contentDims.height);
607 height += nHeight + sHeight;
609 width += insets.left + insets.right;
610 height += insets.top + insets.bottom;
612 return new Dimension(width, height);
616 * This method is called when a Component is removed from the
617 * JInternalFrame.
619 * @param c The Component that was removed.
621 public void removeLayoutComponent(Component c)
623 // Nothing to do here.
628 * This helper class is used to listen to the JDesktopPane's glassPane for
629 * MouseEvents. The JInternalFrame can then be selected if a click is
630 * detected on its children.
632 protected class GlassPaneDispatcher implements MouseInputListener
634 /** The MouseEvent target. */
635 private transient Component mouseEventTarget;
637 /** The component pressed. */
638 private transient Component pressedComponent;
640 /** The last component entered. */
641 private transient Component lastComponentEntered;
643 /** Used to store/reset lastComponentEntered. */
644 private transient Component tempComponent;
646 /** The number of presses. */
647 private transient int pressCount;
650 * This method is called when the mouse enters the glass pane.
652 * @param e
653 * The MouseEvent.
655 public void mouseEntered(MouseEvent e)
657 handleEvent(e);
661 * This method is called when the mouse is clicked on the glass pane.
663 * @param e
664 * The MouseEvent.
666 public void mouseClicked(MouseEvent e)
668 handleEvent(e);
672 * This method is called when the mouse is dragged in the glass pane.
674 * @param e
675 * The MouseEvent.
677 public void mouseDragged(MouseEvent e)
679 handleEvent(e);
683 * This method is called when the mouse exits the glass pane.
685 * @param e
686 * The MouseEvent.
688 public void mouseExited(MouseEvent e)
690 handleEvent(e);
694 * This method is called when the mouse is moved in the glass pane.
696 * @param e
697 * The MouseEvent.
699 public void mouseMoved(MouseEvent e)
701 handleEvent(e);
705 * This method is called when the mouse is pressed in the glass pane.
707 * @param e
708 * The MouseEvent.
710 public void mousePressed(MouseEvent e)
712 activateFrame(frame);
713 handleEvent(e);
717 * This method is called when the mouse is released in the glass pane.
719 * @param e
720 * The MouseEvent.
722 public void mouseReleased(MouseEvent e)
724 handleEvent(e);
728 * This method acquires a candidate component to dispatch the MouseEvent to.
730 * @param me
731 * The MouseEvent to acquire a component for.
733 private void acquireComponentForMouseEvent(MouseEvent me)
735 int x = me.getX();
736 int y = me.getY();
738 // Find the candidate which should receive this event.
739 Component parent = frame.getLayeredPane();
740 if (parent == null)
741 return;
742 Component candidate = null;
743 Point p = me.getPoint();
744 while (candidate == null && parent != null)
746 candidate = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
747 if (candidate == null)
749 p = SwingUtilities.convertPoint(parent, p.x, p.y,
750 parent.getParent());
751 parent = parent.getParent();
755 // If the only candidate we found was the native container itself,
756 // don't dispatch any event at all. We only care about the lightweight
757 // children here.
758 if (candidate == frame.getContentPane())
759 candidate = null;
761 // If our candidate is new, inform the old target we're leaving.
762 if (lastComponentEntered != null && lastComponentEntered.isShowing()
763 && lastComponentEntered != candidate)
765 Point tp = SwingUtilities.convertPoint(frame.getContentPane(), x, y,
766 lastComponentEntered);
767 MouseEvent exited = new MouseEvent(lastComponentEntered,
768 MouseEvent.MOUSE_EXITED,
769 me.getWhen(), me.getModifiersEx(),
770 tp.x, tp.y, me.getClickCount(),
771 me.isPopupTrigger(),
772 me.getButton());
773 tempComponent = lastComponentEntered;
774 lastComponentEntered = null;
775 tempComponent.dispatchEvent(exited);
778 // If we have a candidate, maybe enter it.
779 if (candidate != null)
781 mouseEventTarget = candidate;
782 if (candidate.isLightweight() && candidate.isShowing()
783 && candidate != frame.getContentPane()
784 && candidate != lastComponentEntered)
786 lastComponentEntered = mouseEventTarget;
787 Point cp = SwingUtilities.convertPoint(frame.getContentPane(), x,
788 y, lastComponentEntered);
789 MouseEvent entered = new MouseEvent(lastComponentEntered,
790 MouseEvent.MOUSE_ENTERED,
791 me.getWhen(),
792 me.getModifiersEx(), cp.x,
793 cp.y, me.getClickCount(),
794 me.isPopupTrigger(),
795 me.getButton());
796 lastComponentEntered.dispatchEvent(entered);
800 if (me.getID() == MouseEvent.MOUSE_RELEASED
801 || me.getID() == MouseEvent.MOUSE_PRESSED && pressCount > 0
802 || me.getID() == MouseEvent.MOUSE_DRAGGED)
803 // If any of the following events occur while a button is held down,
804 // they should be dispatched to the same component to which the
805 // original MOUSE_PRESSED event was dispatched:
806 // - MOUSE_RELEASED
807 // - MOUSE_PRESSED: another button pressed while the first is held down
808 // - MOUSE_DRAGGED
809 mouseEventTarget = pressedComponent;
810 else if (me.getID() == MouseEvent.MOUSE_CLICKED)
812 // Don't dispatch CLICKED events whose target is not the same as the
813 // target for the original PRESSED event.
814 if (candidate != pressedComponent)
815 mouseEventTarget = null;
816 else if (pressCount == 0)
817 pressedComponent = null;
822 * This is a helper method that dispatches the GlassPane MouseEvents to the
823 * proper component.
825 * @param e
826 * The AWTEvent to be dispatched. Usually an instance of
827 * MouseEvent.
829 private void handleEvent(AWTEvent e)
831 if (e instanceof MouseEvent)
833 MouseEvent me = (MouseEvent) e;
834 acquireComponentForMouseEvent(me);
836 //If there is no target, return
837 if (mouseEventTarget == null)
838 return;
840 //Avoid re-dispatching to ourselves and causing an infinite loop
841 if (mouseEventTarget.equals(frame.getGlassPane()))
842 return;
844 // Avoid dispatching ENTERED and EXITED events twice.
845 if (mouseEventTarget.isShowing()
846 && e.getID() != MouseEvent.MOUSE_ENTERED
847 && e.getID() != MouseEvent.MOUSE_EXITED)
849 MouseEvent newEvt = SwingUtilities.convertMouseEvent(
850 frame.getGlassPane(),
852 mouseEventTarget);
853 mouseEventTarget.dispatchEvent(newEvt);
855 switch (e.getID())
857 case MouseEvent.MOUSE_PRESSED:
858 if (pressCount++ == 0)
859 pressedComponent = mouseEventTarget;
860 break;
861 case MouseEvent.MOUSE_RELEASED:
862 // Clear our memory of the original PRESSED event, only if
863 // we're not expecting a CLICKED event after this. If
864 // there is a CLICKED event after this, it will do clean up.
865 if (--pressCount == 0 && mouseEventTarget != pressedComponent)
866 pressedComponent = null;
867 break;
875 * This helper class listens for PropertyChangeEvents from the
876 * JInternalFrame.
878 public class InternalFramePropertyChangeListener
879 implements PropertyChangeListener
883 * This method is called when one of the JInternalFrame's properties change.
885 * @param evt
886 * The PropertyChangeEvent.
888 public void propertyChange(PropertyChangeEvent evt)
890 if (evt.getPropertyName().equals(JInternalFrame.IS_MAXIMUM_PROPERTY))
892 if (frame.isMaximum())
893 maximizeFrame(frame);
894 else
895 minimizeFrame(frame);
897 else if (evt.getPropertyName().equals(JInternalFrame.IS_ICON_PROPERTY))
899 if (frame.isIcon())
900 iconifyFrame(frame);
901 else
902 deiconifyFrame(frame);
904 else if (evt.getPropertyName().equals(JInternalFrame.IS_SELECTED_PROPERTY))
906 if (frame.isSelected())
907 activateFrame(frame);
908 else
909 deactivateFrame(frame);
911 else if (evt.getPropertyName().equals(JInternalFrame.ROOT_PANE_PROPERTY)
912 || evt.getPropertyName().equals(
913 JInternalFrame.GLASS_PANE_PROPERTY))
915 Component old = (Component) evt.getOldValue();
916 old.removeMouseListener(glassPaneDispatcher);
917 old.removeMouseMotionListener(glassPaneDispatcher);
919 Component newPane = (Component) evt.getNewValue();
920 newPane.addMouseListener(glassPaneDispatcher);
921 newPane.addMouseMotionListener(glassPaneDispatcher);
923 frame.revalidate();
926 * FIXME: need to add ancestor properties to JComponents. else if
927 * (evt.getPropertyName().equals(JComponent.ANCESTOR_PROPERTY)) { if
928 * (desktopPane != null)
929 * desktopPane.removeComponentListener(componentListener); desktopPane =
930 * frame.getDesktopPane(); if (desktopPane != null)
931 * desktopPane.addComponentListener(componentListener); }
937 * This helper class is the border for the JInternalFrame.
939 private class InternalFrameBorder extends AbstractBorder implements
940 UIResource
942 /** The width of the border. */
943 private static final int bSize = 5;
945 /** The size of the corners. */
946 private static final int offset = 10;
949 * This method returns whether the border is opaque.
951 * @return Whether the border is opaque.
953 public boolean isBorderOpaque()
955 return true;
959 * This method returns the insets of the border.
961 * @param c
962 * The Component to find border insets for.
963 * @return The border insets.
965 public Insets getBorderInsets(Component c)
967 return new Insets(bSize, bSize, bSize, bSize);
971 * This method paints the border.
973 * @param c
974 * The Component that owns the border.
975 * @param g
976 * The Graphics object to paint with.
977 * @param x
978 * The x coordinate to paint at.
979 * @param y
980 * The y coordinate to paint at.
981 * @param width
982 * The width of the Component.
983 * @param height
984 * The height of the Component.
986 public void paintBorder(Component c, Graphics g, int x, int y, int width,
987 int height)
989 g.translate(x, y);
990 Color saved = g.getColor();
991 Rectangle b = frame.getBounds();
993 Color d = c.getBackground();
994 g.setColor(d);
995 g.fillRect(0, 0, bSize, b.height);
996 g.fillRect(0, 0, b.width, bSize);
997 g.fillRect(0, b.height - bSize, b.width, bSize);
998 g.fillRect(b.width - bSize, 0, bSize, b.height);
1000 int x1 = 0;
1001 int x2 = bSize;
1002 int x3 = b.width - bSize;
1003 int x4 = b.width;
1005 int y1 = 0;
1006 int y2 = bSize;
1007 int y3 = b.height - bSize;
1008 int y4 = b.height;
1010 g.setColor(Color.GRAY);
1011 g.fillRect(0, 0, bSize, y4);
1012 g.fillRect(0, 0, x4, bSize);
1013 g.fillRect(0, y3, b.width, bSize);
1014 g.fillRect(x3, 0, bSize, b.height);
1016 g.fill3DRect(0, offset, bSize, b.height - 2 * offset, false);
1017 g.fill3DRect(offset, 0, b.width - 2 * offset, bSize, false);
1018 g.fill3DRect(offset, b.height - bSize, b.width - 2 * offset, bSize, false);
1019 g.fill3DRect(b.width - bSize, offset, bSize, b.height - 2 * offset, false);
1021 g.translate(-x, -y);
1022 g.setColor(saved);
1027 * The MouseListener that is responsible for dragging and resizing the
1028 * JInternalFrame in response to MouseEvents.
1030 protected MouseInputAdapter borderListener;
1033 * The ComponentListener that is responsible for resizing the JInternalFrame
1034 * in response to ComponentEvents from the JDesktopPane.
1036 protected ComponentListener componentListener;
1039 * The MouseListener that is responsible for activating the JInternalFrame
1040 * when the mouse press activates one of its descendents.
1042 protected MouseInputListener glassPaneDispatcher;
1045 * The PropertyChangeListener that is responsible for listening to
1046 * PropertyChangeEvents from the JInternalFrame.
1048 protected PropertyChangeListener propertyChangeListener;
1050 /** The InternalFrameListener that listens to the JInternalFrame. */
1051 private transient BasicInternalFrameListener internalFrameListener;
1053 /** The JComponent placed at the east region of the JInternalFrame. */
1054 protected JComponent eastPane;
1056 /** The JComponent placed at the north region of the JInternalFrame. */
1057 protected JComponent northPane;
1059 /** The JComponent placed at the south region of the JInternalFrame. */
1060 protected JComponent southPane;
1062 /** The JComponent placed at the west region of the JInternalFrame. */
1063 protected JComponent westPane;
1066 * The Keystroke bound to open the menu.
1067 * @deprecated
1069 protected KeyStroke openMenuKey;
1071 /** The TitlePane displayed at the top of the JInternalFrame. */
1072 protected BasicInternalFrameTitlePane titlePane;
1074 /** The JInternalFrame this UI is responsible for. */
1075 protected JInternalFrame frame;
1077 /** The LayoutManager used in the JInternalFrame. */
1078 protected LayoutManager internalFrameLayout;
1080 /** The JDesktopPane that is the parent of the JInternalFrame. */
1081 private transient JDesktopPane desktopPane;
1084 * Creates a new BasicInternalFrameUI object.
1086 * @param b The JInternalFrame this UI will represent.
1088 public BasicInternalFrameUI(JInternalFrame b)
1090 // Nothing to do here.
1094 * This method will create a new BasicInternalFrameUI for the given
1095 * JComponent.
1097 * @param b The JComponent to create a BasicInternalFrameUI for.
1099 * @return A new BasicInternalFrameUI.
1101 public static ComponentUI createUI(JComponent b)
1103 return new BasicInternalFrameUI((JInternalFrame) b);
1107 * This method installs a UI for the JInternalFrame.
1109 * @param c The JComponent to install this UI on.
1111 public void installUI(JComponent c)
1113 if (c instanceof JInternalFrame)
1115 frame = (JInternalFrame) c;
1117 installDefaults();
1118 installListeners();
1119 installComponents();
1120 installKeyboardActions();
1122 ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(false);
1123 if (! frame.isSelected())
1124 frame.getRootPane().getGlassPane().setVisible(true);
1126 frame.setOpaque(true);
1127 frame.invalidate();
1132 * This method reverses the work done by installUI.
1134 * @param c The JComponent to uninstall this UI for.
1136 public void uninstallUI(JComponent c)
1138 uninstallKeyboardActions();
1139 uninstallComponents();
1140 uninstallListeners();
1141 uninstallDefaults();
1143 ((JComponent) frame.getRootPane().getGlassPane()).setOpaque(true);
1144 frame.getRootPane().getGlassPane().setVisible(false);
1146 frame = null;
1150 * This method installs the defaults specified by the look and feel.
1152 protected void installDefaults()
1154 internalFrameLayout = createLayoutManager();
1155 frame.setLayout(internalFrameLayout);
1156 LookAndFeel.installBorder(frame, "InternalFrame.border");
1157 frame.setFrameIcon(UIManager.getIcon("InternalFrame.icon"));
1161 * This method installs the keyboard actions for the JInternalFrame.
1163 protected void installKeyboardActions()
1165 // FIXME: Implement.
1169 * This method installs the Components for the JInternalFrame.
1171 protected void installComponents()
1173 setNorthPane(createNorthPane(frame));
1174 setSouthPane(createSouthPane(frame));
1175 setEastPane(createEastPane(frame));
1176 setWestPane(createWestPane(frame));
1180 * This method installs the listeners for the JInternalFrame.
1182 protected void installListeners()
1184 glassPaneDispatcher = createGlassPaneDispatcher();
1185 createInternalFrameListener();
1186 borderListener = createBorderListener(frame);
1187 componentListener = createComponentListener();
1188 propertyChangeListener = createPropertyChangeListener();
1190 frame.addMouseListener(borderListener);
1191 frame.addMouseMotionListener(borderListener);
1192 frame.addInternalFrameListener(internalFrameListener);
1193 frame.addPropertyChangeListener(propertyChangeListener);
1194 frame.getRootPane().getGlassPane().addMouseListener(glassPaneDispatcher);
1195 frame.getRootPane().getGlassPane().addMouseMotionListener(glassPaneDispatcher);
1199 * This method uninstalls the defaults for the JInternalFrame.
1201 protected void uninstallDefaults()
1203 frame.setBorder(null);
1204 frame.setLayout(null);
1205 internalFrameLayout = null;
1209 * This method uninstalls the Components for the JInternalFrame.
1211 protected void uninstallComponents()
1213 setNorthPane(null);
1214 setSouthPane(null);
1215 setEastPane(null);
1216 setWestPane(null);
1220 * This method uninstalls the listeners for the JInternalFrame.
1222 protected void uninstallListeners()
1224 if (desktopPane != null)
1225 desktopPane.removeComponentListener(componentListener);
1227 frame.getRootPane().getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
1228 frame.getRootPane().getGlassPane().removeMouseListener(glassPaneDispatcher);
1230 frame.removePropertyChangeListener(propertyChangeListener);
1231 frame.removeInternalFrameListener(internalFrameListener);
1232 frame.removeMouseMotionListener(borderListener);
1233 frame.removeMouseListener(borderListener);
1235 propertyChangeListener = null;
1236 componentListener = null;
1237 borderListener = null;
1238 internalFrameListener = null;
1239 glassPaneDispatcher = null;
1243 * This method uninstalls the keyboard actions for the JInternalFrame.
1245 protected void uninstallKeyboardActions()
1247 // FIXME: Implement.
1251 * This method creates a new LayoutManager for the JInternalFrame.
1253 * @return A new LayoutManager for the JInternalFrame.
1255 protected LayoutManager createLayoutManager()
1257 return new InternalFrameLayout();
1261 * This method creates a new PropertyChangeListener for the JInternalFrame.
1263 * @return A new PropertyChangeListener for the JInternalFrame.
1265 protected PropertyChangeListener createPropertyChangeListener()
1267 return new InternalFramePropertyChangeListener();
1271 * This method returns the preferred size of the given JComponent.
1273 * @param x The JComponent to find a preferred size for.
1275 * @return The preferred size.
1277 public Dimension getPreferredSize(JComponent x)
1279 Dimension pref = null;
1280 LayoutManager layout = frame.getLayout();
1281 if (frame == x && layout != null)
1282 pref = layout.preferredLayoutSize(frame);
1283 else
1284 pref = new Dimension(100, 100);
1285 return pref;
1289 * This method returns the minimum size of the given JComponent.
1291 * @param x The JComponent to find a minimum size for.
1293 * @return The minimum size.
1295 public Dimension getMinimumSize(JComponent x)
1297 Dimension min = null;
1298 LayoutManager layout = frame.getLayout();
1299 if (frame == x && layout != null)
1300 min = layout.minimumLayoutSize(frame);
1301 else
1302 min = new Dimension(0, 0);
1303 return min;
1307 * This method returns the maximum size of the given JComponent.
1309 * @param x The JComponent to find a maximum size for.
1311 * @return The maximum size.
1313 public Dimension getMaximumSize(JComponent x)
1315 Dimension max = null;
1316 LayoutManager layout = frame.getLayout();
1317 if (frame == x && layout != null && layout instanceof LayoutManager2)
1318 max = ((LayoutManager2) layout).maximumLayoutSize(frame);
1319 else
1320 max = new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
1321 return max;
1325 * This method replaces the currentPane with the newPane. When replacing it
1326 * also removes the MouseHandlers for the old pane and installs them on
1327 * the new pane.
1329 * @param currentPane The old pane to remove.
1330 * @param newPane The new pane to install.
1332 protected void replacePane(JComponent currentPane, JComponent newPane)
1334 if (currentPane != null)
1336 deinstallMouseHandlers(currentPane);
1337 frame.remove(currentPane);
1340 if (newPane != null)
1342 installMouseHandlers(newPane);
1343 frame.add(newPane);
1348 * This method removes the necessary MouseListeners from the given
1349 * JComponent.
1351 * @param c The JComponent to remove MouseListeners from.
1353 protected void deinstallMouseHandlers(JComponent c)
1355 c.removeMouseListener(borderListener);
1356 c.removeMouseMotionListener(borderListener);
1360 * This method installs the necessary MouseListeners from the given
1361 * JComponent.
1363 * @param c The JComponent to install MouseListeners on.
1365 protected void installMouseHandlers(JComponent c)
1367 c.addMouseListener(borderListener);
1368 c.addMouseMotionListener(borderListener);
1372 * This method creates the north pane used in the JInternalFrame.
1374 * @param w The JInternalFrame to create a north pane for.
1376 * @return The north pane.
1378 protected JComponent createNorthPane(JInternalFrame w)
1380 titlePane = new BasicInternalFrameTitlePane(w);
1381 return titlePane;
1385 * This method creates the west pane used in the JInternalFrame.
1387 * @param w The JInternalFrame to create a west pane for.
1389 * @return The west pane.
1391 protected JComponent createWestPane(JInternalFrame w)
1393 return null;
1397 * This method creates the south pane used in the JInternalFrame.
1399 * @param w The JInternalFrame to create a south pane for.
1401 * @return The south pane.
1403 protected JComponent createSouthPane(JInternalFrame w)
1405 return null;
1409 * This method creates the east pane used in the JInternalFrame.
1411 * @param w The JInternalFrame to create an east pane for.
1413 * @return The east pane.
1415 protected JComponent createEastPane(JInternalFrame w)
1417 return null;
1421 * This method returns a new BorderListener for the given JInternalFrame.
1423 * @param w The JIntenalFrame to create a BorderListener for.
1425 * @return A new BorderListener.
1427 protected MouseInputAdapter createBorderListener(JInternalFrame w)
1429 return new BorderListener();
1433 * This method creates a new InternalFrameListener for the JInternalFrame.
1435 protected void createInternalFrameListener()
1437 internalFrameListener = new BasicInternalFrameListener();
1441 * DOCUMENT ME!
1443 * @return DOCUMENT ME!
1445 protected final boolean isKeyBindingRegistered()
1447 // FIXME: Implement.
1448 return false;
1452 * DOCUMENT ME!
1454 * @param b DOCUMENT ME!
1456 protected final void setKeyBindingRegistered(boolean b)
1458 // FIXME: Implement.
1462 * DOCUMENT ME!
1464 * @return DOCUMENT ME!
1466 public final boolean isKeyBindingActive()
1468 // FIXME: Implement.
1469 return false;
1473 * DOCUMENT ME!
1475 * @param b DOCUMENT ME!
1477 protected final void setKeyBindingActive(boolean b)
1479 // FIXME: Implement.
1483 * DOCUMENT ME!
1485 protected void setupMenuOpenKey()
1487 // FIXME: Implement.
1491 * DOCUMENT ME!
1493 protected void setupMenuCloseKey()
1495 // FIXME: Implement.
1499 * This method returns the north pane.
1501 * @return The north pane.
1503 public JComponent getNorthPane()
1505 return northPane;
1509 * This method sets the north pane to be the given JComponent.
1511 * @param c The new north pane.
1513 public void setNorthPane(JComponent c)
1515 replacePane(northPane, c);
1516 northPane = c;
1520 * This method returns the south pane.
1522 * @return The south pane.
1524 public JComponent getSouthPane()
1526 return southPane;
1530 * This method sets the south pane to be the given JComponent.
1532 * @param c The new south pane.
1534 public void setSouthPane(JComponent c)
1536 replacePane(southPane, c);
1537 southPane = c;
1541 * This method sets the east pane to be the given JComponent.
1543 * @param c The new east pane.
1545 public void setEastPane(JComponent c)
1547 replacePane(eastPane, c);
1548 eastPane = c;
1552 * This method returns the east pane.
1554 * @return The east pane.
1556 public JComponent getEastPane()
1558 return eastPane;
1562 * This method sets the west pane to be the given JComponent.
1564 * @param c The new west pane.
1566 public void setWestPane(JComponent c)
1568 replacePane(westPane, c);
1569 westPane = c;
1573 * This method returns the west pane.
1575 * @return The west pane.
1577 public JComponent getWestPane()
1579 return westPane;
1583 * This method returns the DesktopManager to use with the JInternalFrame.
1585 * @return The DesktopManager to use with the JInternalFrame.
1587 protected DesktopManager getDesktopManager()
1589 DesktopManager value = null;
1590 JDesktopPane pane = frame.getDesktopPane();
1591 if (pane != null)
1592 value = frame.getDesktopPane().getDesktopManager();
1593 if (value == null)
1594 value = createDesktopManager();
1595 return value;
1599 * This method returns a default DesktopManager that can be used with this
1600 * JInternalFrame.
1602 * @return A default DesktopManager that can be used with this
1603 * JInternalFrame.
1605 protected DesktopManager createDesktopManager()
1607 return new DefaultDesktopManager();
1611 * This is a convenience method that closes the JInternalFrame.
1613 * @param f The JInternalFrame to close.
1615 protected void closeFrame(JInternalFrame f)
1617 getDesktopManager().closeFrame(f);
1621 * This is a convenience method that maximizes the JInternalFrame.
1623 * @param f The JInternalFrame to maximize.
1625 protected void maximizeFrame(JInternalFrame f)
1627 getDesktopManager().maximizeFrame(f);
1631 * This is a convenience method that minimizes the JInternalFrame.
1633 * @param f The JInternalFrame to minimize.
1635 protected void minimizeFrame(JInternalFrame f)
1637 getDesktopManager().minimizeFrame(f);
1641 * This is a convenience method that iconifies the JInternalFrame.
1643 * @param f The JInternalFrame to iconify.
1645 protected void iconifyFrame(JInternalFrame f)
1647 getDesktopManager().iconifyFrame(f);
1651 * This is a convenience method that deiconifies the JInternalFrame.
1653 * @param f The JInternalFrame to deiconify.
1655 protected void deiconifyFrame(JInternalFrame f)
1657 getDesktopManager().deiconifyFrame(f);
1661 * This is a convenience method that activates the JInternalFrame.
1663 * @param f The JInternalFrame to activate.
1665 protected void activateFrame(JInternalFrame f)
1667 getDesktopManager().activateFrame(f);
1671 * This is a convenience method that deactivates the JInternalFrame.
1673 * @param f the JInternalFrame to deactivate
1675 protected void deactivateFrame(JInternalFrame f)
1677 getDesktopManager().deactivateFrame(f);
1681 * This method returns a new ComponentListener for the JDesktopPane.
1683 * @return A new ComponentListener.
1685 protected ComponentListener createComponentListener()
1687 return new ComponentHandler();
1691 * This method returns a new GlassPaneDispatcher.
1693 * @return A new GlassPaneDispatcher.
1695 protected MouseInputListener createGlassPaneDispatcher()
1697 return new GlassPaneDispatcher();