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)
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
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
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
;
57 import java
.beans
.PropertyVetoException
;
58 import java
.beans
.VetoableChangeListener
;
60 import javax
.swing
.DefaultDesktopManager
;
61 import javax
.swing
.DesktopManager
;
62 import javax
.swing
.JComponent
;
63 import javax
.swing
.JDesktopPane
;
64 import javax
.swing
.JInternalFrame
;
65 import javax
.swing
.KeyStroke
;
66 import javax
.swing
.LookAndFeel
;
67 import javax
.swing
.SwingConstants
;
68 import javax
.swing
.SwingUtilities
;
69 import javax
.swing
.UIManager
;
70 import javax
.swing
.border
.AbstractBorder
;
71 import javax
.swing
.event
.InternalFrameEvent
;
72 import javax
.swing
.event
.InternalFrameListener
;
73 import javax
.swing
.event
.MouseInputAdapter
;
74 import javax
.swing
.event
.MouseInputListener
;
75 import javax
.swing
.plaf
.ComponentUI
;
76 import javax
.swing
.plaf
.InternalFrameUI
;
77 import javax
.swing
.plaf
.UIResource
;
80 * This is the UI delegate for the Basic look and feel for JInternalFrames.
82 public class BasicInternalFrameUI
extends InternalFrameUI
85 * This is a helper class that listens to the JInternalFrame for
86 * InternalFrameEvents.
88 protected class BasicInternalFrameListener
implements InternalFrameListener
91 * This method is called when the JInternalFrame is activated.
93 * @param e The InternalFrameEvent.
95 public void internalFrameActivated(InternalFrameEvent e
)
101 * This method is called when the JInternalFrame is closed.
103 * @param e The InternalFrameEvent.
105 public void internalFrameClosed(InternalFrameEvent e
)
111 * This method is called when the JInternalFrame is closing.
113 * @param e The InternalFrameEvent.
115 public void internalFrameClosing(InternalFrameEvent e
)
121 * This method is called when the JInternalFrame is deactivated.
123 * @param e The InternalFrameEvent.
125 public void internalFrameDeactivated(InternalFrameEvent e
)
131 * This method is called when the JInternalFrame is deiconified.
133 * @param e The InternalFrameEvent.
135 public void internalFrameDeiconified(InternalFrameEvent e
)
141 * This method is called when the JInternalFrame is iconified.
143 * @param e The InternalFrameEvent.
145 public void internalFrameIconified(InternalFrameEvent e
)
151 * This method is called when the JInternalFrame is opened.
153 * @param e The InternalFrameEvent.
155 public void internalFrameOpened(InternalFrameEvent e
)
162 * This helper class listens to the edges of the JInternalFrame and the
163 * TitlePane for mouse events. It is responsible for dragging and resizing
164 * the JInternalFrame in response to the MouseEvents.
166 protected class BorderListener
extends MouseInputAdapter
167 implements SwingConstants
169 /** FIXME: Use for something. */
170 protected final int RESIZE_NONE
= 0;
172 /** The x offset from the top left corner of the JInternalFrame. */
173 private transient int xOffset
= 0;
175 /** The y offset from the top left corner of the JInternalFrame. */
176 private transient int yOffset
= 0;
178 /** The direction that the resize is occuring in. */
179 private transient int direction
= -1;
181 /** Cache rectangle that can be reused. */
182 private transient Rectangle cacheRect
= new Rectangle();
185 * This method is called when the mouse is clicked.
187 * @param e The MouseEvent.
189 public void mouseClicked(MouseEvent e
)
191 // There is nothing to do when the mouse is clicked
196 * This method is called when the mouse is dragged. This method is
197 * responsible for resizing or dragging the JInternalFrame.
199 * @param e The MouseEvent.
201 public void mouseDragged(MouseEvent e
)
203 // If the frame is maximized, there is nothing that
204 // can be dragged around.
205 if (frame
.isMaximum())
207 DesktopManager dm
= getDesktopManager();
208 Rectangle b
= frame
.getBounds();
209 Dimension min
= frame
.getMinimumSize();
211 min
= new Dimension(0, 0);
212 Insets insets
= frame
.getInsets();
215 if (e
.getSource() == frame
&& frame
.isResizable())
220 cacheRect
.setBounds(b
.x
, Math
.min(b
.y
+ y
, b
.y
+ b
.height
222 b
.width
, b
.height
- y
);
225 cacheRect
.setBounds(b
.x
, Math
.min(b
.y
+ y
, b
.y
+ b
.height
230 cacheRect
.setBounds(b
.x
, b
.y
, x
, b
.height
);
233 cacheRect
.setBounds(b
.x
, b
.y
, x
, y
);
236 cacheRect
.setBounds(b
.x
, b
.y
, b
.width
, y
);
239 cacheRect
.setBounds(Math
.min(b
.x
+ x
, b
.x
+ b
.width
- min
.width
),
240 b
.y
, b
.width
- x
, y
);
243 cacheRect
.setBounds(Math
.min(b
.x
+ x
, b
.x
+ b
.width
- min
.width
),
244 b
.y
, b
.width
- x
, b
.height
);
248 Math
.min(b
.x
+ x
, b
.x
+ b
.width
- min
.width
),
249 Math
.min(b
.y
+ y
, b
.y
+ b
.height
- min
.height
),
250 b
.width
- x
, b
.height
- y
);
253 dm
.resizeFrame(frame
, cacheRect
.x
, cacheRect
.y
,
254 Math
.max(min
.width
, cacheRect
.width
),
255 Math
.max(min
.height
, cacheRect
.height
));
257 else if (e
.getSource() == titlePane
)
259 Rectangle fBounds
= frame
.getBounds();
261 dm
.dragFrame(frame
, e
.getX() - xOffset
+ b
.x
, e
.getY() - yOffset
267 * This method is called when the mouse exits the JInternalFrame.
269 * @param e The MouseEvent.
271 public void mouseExited(MouseEvent e
)
273 // There is nothing to do when the mouse exits
278 * This method is called when the mouse is moved inside the
281 * @param e The MouseEvent.
283 public void mouseMoved(MouseEvent e
)
285 // There is nothing to do when the mouse moves
286 // over the border area.
290 * This method is called when the mouse is pressed.
292 * @param e The MouseEvent.
294 public void mousePressed(MouseEvent e
)
296 activateFrame(frame
);
297 DesktopManager dm
= getDesktopManager();
300 Insets insets
= frame
.getInsets();
302 if (e
.getSource() == frame
&& frame
.isResizable())
304 direction
= sectionOfClick(x
, y
);
305 dm
.beginResizingFrame(frame
, direction
);
307 else if (e
.getSource() == titlePane
)
309 Rectangle tBounds
= titlePane
.getBounds();
311 xOffset
= e
.getX() - tBounds
.x
+ insets
.left
;
312 yOffset
= e
.getY() - tBounds
.y
+ insets
.top
;
314 dm
.beginDraggingFrame(frame
);
319 * This method is called when the mouse is released.
321 * @param e The MouseEvent.
323 public void mouseReleased(MouseEvent e
)
325 DesktopManager dm
= getDesktopManager();
328 if (e
.getSource() == frame
&& frame
.isResizable())
329 dm
.endResizingFrame(frame
);
330 else if (e
.getSource() == titlePane
)
331 dm
.endDraggingFrame(frame
);
335 * This method determines the direction of the resize based on the
336 * coordinates and the size of the JInternalFrame.
338 * @param x The x coordinate of the MouseEvent.
339 * @param y The y coordinate of the MouseEvent.
341 * @return The direction of the resize (a SwingConstant direction).
343 private int sectionOfClick(int x
, int y
)
345 Insets insets
= frame
.getInsets();
346 Rectangle b
= frame
.getBounds();
347 if (x
< insets
.left
&& y
< insets
.top
)
349 else if (x
> b
.width
- insets
.right
&& y
< insets
.top
)
351 else if (x
> b
.width
- insets
.right
&& y
> b
.height
- insets
.bottom
)
353 else if (x
< insets
.left
&& y
> b
.height
- insets
.bottom
)
355 else if (y
< insets
.top
)
357 else if (x
< insets
.left
)
359 else if (y
> b
.height
- insets
.bottom
)
361 else if (x
> b
.width
- insets
.right
)
369 * This helper class listens to the JDesktopPane that parents this
370 * JInternalFrame and listens for resize events and resizes the
371 * JInternalFrame appropriately.
373 protected class ComponentHandler
implements ComponentListener
376 * This method is called when the JDesktopPane is hidden.
379 * The ComponentEvent fired.
381 public void componentHidden(ComponentEvent e
)
387 * This method is called when the JDesktopPane is moved.
390 * The ComponentEvent fired.
392 public void componentMoved(ComponentEvent e
)
398 * This method is called when the JDesktopPane is resized.
401 * The ComponentEvent fired.
403 public void componentResized(ComponentEvent e
)
405 if (frame
.isMaximum())
407 JDesktopPane pane
= (JDesktopPane
) e
.getSource();
408 Insets insets
= pane
.getInsets();
409 Rectangle bounds
= pane
.getBounds();
411 frame
.setBounds(bounds
.x
+ insets
.left
, bounds
.y
+ insets
.top
,
412 bounds
.width
- insets
.left
- insets
.right
,
413 bounds
.height
- insets
.top
- insets
.bottom
);
418 // Sun also resizes the icons. but it doesn't seem to do anything.
422 * This method is called when the JDesktopPane is shown.
425 * The ComponentEvent fired.
427 public void componentShown(ComponentEvent e
)
434 * This helper class acts as the LayoutManager for JInternalFrames.
436 public class InternalFrameLayout
implements LayoutManager
439 * This method is called when the given Component is added to the
443 * The name of the Component.
445 * The Component added.
447 public void addLayoutComponent(String name
, Component c
)
449 // Nothing to do here.
453 * This method is used to set the bounds of the children of the
457 * The Container to lay out.
459 public void layoutContainer(Container c
)
461 Dimension dims
= frame
.getSize();
462 Insets insets
= frame
.getInsets();
464 dims
.width
-= insets
.left
+ insets
.right
;
465 dims
.height
-= insets
.top
+ insets
.bottom
;
467 frame
.getRootPane().getGlassPane().setBounds(0, 0, dims
.width
,
474 if (northPane
!= null)
476 Dimension nDims
= northPane
.getPreferredSize();
477 nh
= Math
.min(nDims
.height
, dims
.height
);
479 northPane
.setBounds(insets
.left
, insets
.top
, dims
.width
, nh
);
482 if (southPane
!= null)
484 Dimension sDims
= southPane
.getPreferredSize();
485 sh
= Math
.min(sDims
.height
, dims
.height
- nh
);
487 southPane
.setBounds(insets
.left
, insets
.top
+ dims
.height
- sh
,
491 int remHeight
= dims
.height
- sh
- nh
;
493 if (westPane
!= null)
495 Dimension wDims
= westPane
.getPreferredSize();
496 ww
= Math
.min(dims
.width
, wDims
.width
);
498 westPane
.setBounds(insets
.left
, insets
.top
+ nh
, ww
, remHeight
);
501 if (eastPane
!= null)
503 Dimension eDims
= eastPane
.getPreferredSize();
504 ew
= Math
.min(eDims
.width
, dims
.width
- ww
);
506 eastPane
.setBounds(insets
.left
+ dims
.width
- ew
, insets
.top
+ nh
,
510 int remWidth
= dims
.width
- ww
- ew
;
512 frame
.getRootPane().setBounds(insets
.left
+ ww
, insets
.top
+ nh
,
513 remWidth
, remHeight
);
517 * This method returns the minimum layout size.
520 * The Container to find a minimum layout size for.
521 * @return The minimum dimensions for the JInternalFrame.
523 public Dimension
minimumLayoutSize(Container c
)
525 return getSize(c
, true);
529 * This method returns the maximum layout size.
532 * The Container to find a maximum layout size for.
533 * @return The maximum dimensions for the JInternalFrame.
535 public Dimension
maximumLayoutSize(Container c
)
537 return preferredLayoutSize(c
);
541 * Th8is method returns the preferred layout size.
544 * The Container to find a preferred layout size for.
545 * @return The preferred dimensions for the JInternalFrame.
547 public Dimension
preferredLayoutSize(Container c
)
549 return getSize(c
, false);
559 * @return DOCUMENT ME!
561 private Dimension
getSize(Container c
, boolean min
)
563 Insets insets
= frame
.getInsets();
565 Dimension contentDims
= frame
.getContentPane().getPreferredSize();
567 contentDims
.width
= contentDims
.height
= 0;
578 if (northPane
!= null)
580 dims
= northPane
.getPreferredSize();
584 nHeight
= dims
.height
;
588 if (southPane
!= null)
590 dims
= southPane
.getPreferredSize();
594 sHeight
= dims
.height
;
598 if (eastPane
!= null)
600 dims
= eastPane
.getPreferredSize();
604 sHeight
= dims
.height
;
608 if (westPane
!= null)
610 dims
= westPane
.getPreferredSize();
614 wHeight
= dims
.height
;
618 int width
= Math
.max(sWidth
, nWidth
);
619 width
= Math
.max(width
, contentDims
.width
+ eWidth
+ wWidth
);
621 int height
= Math
.max(eHeight
, wHeight
);
622 height
= Math
.max(height
, contentDims
.height
);
623 height
+= nHeight
+ sHeight
;
625 width
+= insets
.left
+ insets
.right
;
626 height
+= insets
.top
+ insets
.bottom
;
628 return new Dimension(width
, height
);
632 * This method is called when a Component is removed from the
635 * @param c The Component that was removed.
637 public void removeLayoutComponent(Component c
)
639 // Nothing to do here.
644 * This helper class is used to listen to the JDesktopPane's glassPane for
645 * MouseEvents. The JInternalFrame can then be selected if a click is
646 * detected on its children.
648 protected class GlassPaneDispatcher
implements MouseInputListener
650 /** The MouseEvent target. */
651 private transient Component mouseEventTarget
;
653 /** The component pressed. */
654 private transient Component pressedComponent
;
656 /** The last component entered. */
657 private transient Component lastComponentEntered
;
659 /** Used to store/reset lastComponentEntered. */
660 private transient Component tempComponent
;
662 /** The number of presses. */
663 private transient int pressCount
;
666 * This method is called when the mouse enters the glass pane.
671 public void mouseEntered(MouseEvent e
)
677 * This method is called when the mouse is clicked on the glass pane.
682 public void mouseClicked(MouseEvent e
)
688 * This method is called when the mouse is dragged in the glass pane.
693 public void mouseDragged(MouseEvent e
)
699 * This method is called when the mouse exits the glass pane.
704 public void mouseExited(MouseEvent e
)
710 * This method is called when the mouse is moved in the glass pane.
715 public void mouseMoved(MouseEvent e
)
721 * This method is called when the mouse is pressed in the glass pane.
726 public void mousePressed(MouseEvent e
)
728 activateFrame(frame
);
733 * This method is called when the mouse is released in the glass pane.
738 public void mouseReleased(MouseEvent e
)
744 * This method acquires a candidate component to dispatch the MouseEvent to.
747 * The MouseEvent to acquire a component for.
749 private void acquireComponentForMouseEvent(MouseEvent me
)
754 // Find the candidate which should receive this event.
755 Component parent
= frame
.getLayeredPane();
758 Component candidate
= null;
759 Point p
= me
.getPoint();
760 while (candidate
== null && parent
!= null)
762 candidate
= SwingUtilities
.getDeepestComponentAt(parent
, p
.x
, p
.y
);
763 if (candidate
== null)
765 p
= SwingUtilities
.convertPoint(parent
, p
.x
, p
.y
,
767 parent
= parent
.getParent();
771 // If the only candidate we found was the native container itself,
772 // don't dispatch any event at all. We only care about the lightweight
774 if (candidate
== frame
.getContentPane())
777 // If our candidate is new, inform the old target we're leaving.
778 if (lastComponentEntered
!= null && lastComponentEntered
.isShowing()
779 && lastComponentEntered
!= candidate
)
781 Point tp
= SwingUtilities
.convertPoint(frame
.getContentPane(), x
, y
,
782 lastComponentEntered
);
783 MouseEvent exited
= new MouseEvent(lastComponentEntered
,
784 MouseEvent
.MOUSE_EXITED
,
785 me
.getWhen(), me
.getModifiersEx(),
786 tp
.x
, tp
.y
, me
.getClickCount(),
789 tempComponent
= lastComponentEntered
;
790 lastComponentEntered
= null;
791 tempComponent
.dispatchEvent(exited
);
794 // If we have a candidate, maybe enter it.
795 if (candidate
!= null)
797 mouseEventTarget
= candidate
;
798 if (candidate
.isLightweight() && candidate
.isShowing()
799 && candidate
!= frame
.getContentPane()
800 && candidate
!= lastComponentEntered
)
802 lastComponentEntered
= mouseEventTarget
;
803 Point cp
= SwingUtilities
.convertPoint(frame
.getContentPane(), x
,
804 y
, lastComponentEntered
);
805 MouseEvent entered
= new MouseEvent(lastComponentEntered
,
806 MouseEvent
.MOUSE_ENTERED
,
808 me
.getModifiersEx(), cp
.x
,
809 cp
.y
, me
.getClickCount(),
812 lastComponentEntered
.dispatchEvent(entered
);
816 if (me
.getID() == MouseEvent
.MOUSE_RELEASED
817 || me
.getID() == MouseEvent
.MOUSE_PRESSED
&& pressCount
> 0
818 || me
.getID() == MouseEvent
.MOUSE_DRAGGED
)
819 // If any of the following events occur while a button is held down,
820 // they should be dispatched to the same component to which the
821 // original MOUSE_PRESSED event was dispatched:
823 // - MOUSE_PRESSED: another button pressed while the first is held down
825 mouseEventTarget
= pressedComponent
;
826 else if (me
.getID() == MouseEvent
.MOUSE_CLICKED
)
828 // Don't dispatch CLICKED events whose target is not the same as the
829 // target for the original PRESSED event.
830 if (candidate
!= pressedComponent
)
831 mouseEventTarget
= null;
832 else if (pressCount
== 0)
833 pressedComponent
= null;
838 * This is a helper method that dispatches the GlassPane MouseEvents to the
842 * The AWTEvent to be dispatched. Usually an instance of
845 private void handleEvent(AWTEvent e
)
847 if (e
instanceof MouseEvent
)
849 MouseEvent me
= (MouseEvent
) e
;
850 acquireComponentForMouseEvent(me
);
852 //If there is no target, return
853 if (mouseEventTarget
== null)
856 //Avoid re-dispatching to ourselves and causing an infinite loop
857 if (mouseEventTarget
.equals(frame
.getGlassPane()))
860 // Avoid dispatching ENTERED and EXITED events twice.
861 if (mouseEventTarget
.isShowing()
862 && e
.getID() != MouseEvent
.MOUSE_ENTERED
863 && e
.getID() != MouseEvent
.MOUSE_EXITED
)
865 MouseEvent newEvt
= SwingUtilities
.convertMouseEvent(
866 frame
.getGlassPane(),
869 mouseEventTarget
.dispatchEvent(newEvt
);
873 case MouseEvent
.MOUSE_PRESSED
:
874 if (pressCount
++ == 0)
875 pressedComponent
= mouseEventTarget
;
877 case MouseEvent
.MOUSE_RELEASED
:
878 // Clear our memory of the original PRESSED event, only if
879 // we're not expecting a CLICKED event after this. If
880 // there is a CLICKED event after this, it will do clean up.
881 if (--pressCount
== 0 && mouseEventTarget
!= pressedComponent
)
882 pressedComponent
= null;
891 * This helper class listens for PropertyChangeEvents from the
894 public class InternalFramePropertyChangeListener
implements
895 PropertyChangeListener
, VetoableChangeListener
899 * This method is called when one of the JInternalFrame's properties change.
900 * This method is to allow JInternalFrame to veto an attempt to close the
901 * internal frame. This allows JInternalFrame to honour its
902 * defaultCloseOperation if that is DO_NOTHING_ON_CLOSE.
904 public void vetoableChange(PropertyChangeEvent e
)
905 throws PropertyVetoException
907 if (e
.getPropertyName().equals(JInternalFrame
.IS_CLOSED_PROPERTY
))
909 if (frame
.getDefaultCloseOperation() == JInternalFrame
.HIDE_ON_CLOSE
)
911 frame
.setVisible(false);
912 frame
.getDesktopPane().repaint();
913 throw new PropertyVetoException(
914 "close operation is HIDE_ON_CLOSE\n",
917 else if (frame
.getDefaultCloseOperation() == JInternalFrame
.DISPOSE_ON_CLOSE
)
920 throw new PropertyVetoException(
921 "close operation is DO_NOTHING_ON_CLOSE\n",
927 * This method is called when one of the JInternalFrame's properties change.
930 * The PropertyChangeEvent.
932 public void propertyChange(PropertyChangeEvent evt
)
934 if (evt
.getPropertyName().equals(JInternalFrame
.IS_MAXIMUM_PROPERTY
))
936 if (frame
.isMaximum())
937 maximizeFrame(frame
);
939 minimizeFrame(frame
);
941 else if (evt
.getPropertyName().equals(JInternalFrame
.IS_ICON_PROPERTY
))
946 deiconifyFrame(frame
);
948 else if (evt
.getPropertyName().equals(JInternalFrame
.IS_SELECTED_PROPERTY
))
950 if (frame
.isSelected())
951 activateFrame(frame
);
953 deactivateFrame(frame
);
955 else if (evt
.getPropertyName().equals(JInternalFrame
.ROOT_PANE_PROPERTY
)
956 || evt
.getPropertyName().equals(
957 JInternalFrame
.GLASS_PANE_PROPERTY
))
959 Component old
= (Component
) evt
.getOldValue();
960 old
.removeMouseListener(glassPaneDispatcher
);
961 old
.removeMouseMotionListener(glassPaneDispatcher
);
963 Component newPane
= (Component
) evt
.getNewValue();
964 newPane
.addMouseListener(glassPaneDispatcher
);
965 newPane
.addMouseMotionListener(glassPaneDispatcher
);
970 * FIXME: need to add ancestor properties to JComponents. else if
971 * (evt.getPropertyName().equals(JComponent.ANCESTOR_PROPERTY)) { if
972 * (desktopPane != null)
973 * desktopPane.removeComponentListener(componentListener); desktopPane =
974 * frame.getDesktopPane(); if (desktopPane != null)
975 * desktopPane.addComponentListener(componentListener); }
981 * This helper class is the border for the JInternalFrame.
983 private class InternalFrameBorder
extends AbstractBorder
implements
986 /** The width of the border. */
987 private static final int bSize
= 5;
989 /** The size of the corners. */
990 private static final int offset
= 10;
993 * This method returns whether the border is opaque.
995 * @return Whether the border is opaque.
997 public boolean isBorderOpaque()
1003 * This method returns the insets of the border.
1006 * The Component to find border insets for.
1007 * @return The border insets.
1009 public Insets
getBorderInsets(Component c
)
1011 return new Insets(bSize
, bSize
, bSize
, bSize
);
1015 * This method paints the border.
1018 * The Component that owns the border.
1020 * The Graphics object to paint with.
1022 * The x coordinate to paint at.
1024 * The y coordinate to paint at.
1026 * The width of the Component.
1028 * The height of the Component.
1030 public void paintBorder(Component c
, Graphics g
, int x
, int y
, int width
,
1034 Color saved
= g
.getColor();
1035 Rectangle b
= frame
.getBounds();
1037 Color d
= c
.getBackground();
1039 g
.fillRect(0, 0, bSize
, b
.height
);
1040 g
.fillRect(0, 0, b
.width
, bSize
);
1041 g
.fillRect(0, b
.height
- bSize
, b
.width
, bSize
);
1042 g
.fillRect(b
.width
- bSize
, 0, bSize
, b
.height
);
1046 int x3
= b
.width
- bSize
;
1051 int y3
= b
.height
- bSize
;
1054 g
.setColor(Color
.GRAY
);
1055 g
.fillRect(0, 0, bSize
, y4
);
1056 g
.fillRect(0, 0, x4
, bSize
);
1057 g
.fillRect(0, y3
, b
.width
, bSize
);
1058 g
.fillRect(x3
, 0, bSize
, b
.height
);
1060 g
.fill3DRect(0, offset
, bSize
, b
.height
- 2 * offset
, false);
1061 g
.fill3DRect(offset
, 0, b
.width
- 2 * offset
, bSize
, false);
1062 g
.fill3DRect(offset
, b
.height
- bSize
, b
.width
- 2 * offset
, bSize
, false);
1063 g
.fill3DRect(b
.width
- bSize
, offset
, bSize
, b
.height
- 2 * offset
, false);
1065 g
.translate(-x
, -y
);
1071 * The MouseListener that is responsible for dragging and resizing the
1072 * JInternalFrame in response to MouseEvents.
1074 protected MouseInputAdapter borderListener
;
1077 * The ComponentListener that is responsible for resizing the JInternalFrame
1078 * in response to ComponentEvents from the JDesktopPane.
1080 protected ComponentListener componentListener
;
1083 * The MouseListener that is responsible for activating the JInternalFrame
1084 * when the mouse press activates one of its descendents.
1086 protected MouseInputListener glassPaneDispatcher
;
1089 * The PropertyChangeListener that is responsible for listening to
1090 * PropertyChangeEvents from the JInternalFrame.
1092 protected PropertyChangeListener propertyChangeListener
;
1095 * The VetoableChangeListener. Listens to PropertyChangeEvents
1096 * from the JInternalFrame and allows the JInternalFrame to
1097 * veto attempts to close it.
1099 private VetoableChangeListener internalFrameVetoableChangeListener
;
1101 /** The InternalFrameListener that listens to the JInternalFrame. */
1102 private transient BasicInternalFrameListener internalFrameListener
;
1104 /** The JComponent placed at the east region of the JInternalFrame. */
1105 protected JComponent eastPane
;
1107 /** The JComponent placed at the north region of the JInternalFrame. */
1108 protected JComponent northPane
;
1110 /** The JComponent placed at the south region of the JInternalFrame. */
1111 protected JComponent southPane
;
1113 /** The JComponent placed at the west region of the JInternalFrame. */
1114 protected JComponent westPane
;
1117 * The Keystroke bound to open the menu.
1120 protected KeyStroke openMenuKey
;
1122 /** The TitlePane displayed at the top of the JInternalFrame. */
1123 protected BasicInternalFrameTitlePane titlePane
;
1125 /** The JInternalFrame this UI is responsible for. */
1126 protected JInternalFrame frame
;
1128 /** The LayoutManager used in the JInternalFrame. */
1129 protected LayoutManager internalFrameLayout
;
1131 /** The JDesktopPane that is the parent of the JInternalFrame. */
1132 private transient JDesktopPane desktopPane
;
1135 * Creates a new BasicInternalFrameUI object.
1137 * @param b The JInternalFrame this UI will represent.
1139 public BasicInternalFrameUI(JInternalFrame b
)
1141 // Nothing to do here.
1145 * This method will create a new BasicInternalFrameUI for the given
1148 * @param b The JComponent to create a BasicInternalFrameUI for.
1150 * @return A new BasicInternalFrameUI.
1152 public static ComponentUI
createUI(JComponent b
)
1154 return new BasicInternalFrameUI((JInternalFrame
) b
);
1158 * This method installs a UI for the JInternalFrame.
1160 * @param c The JComponent to install this UI on.
1162 public void installUI(JComponent c
)
1164 if (c
instanceof JInternalFrame
)
1166 frame
= (JInternalFrame
) c
;
1168 ((JComponent
) frame
.getRootPane().getGlassPane()).setOpaque(false);
1169 frame
.getRootPane().getGlassPane().setVisible(true);
1173 installComponents();
1174 installKeyboardActions();
1176 frame
.setOpaque(true);
1182 * This method reverses the work done by installUI.
1184 * @param c The JComponent to uninstall this UI for.
1186 public void uninstallUI(JComponent c
)
1188 uninstallKeyboardActions();
1189 uninstallComponents();
1190 uninstallListeners();
1191 uninstallDefaults();
1193 ((JComponent
) frame
.getRootPane().getGlassPane()).setOpaque(true);
1194 frame
.getRootPane().getGlassPane().setVisible(false);
1200 * This method installs the defaults specified by the look and feel.
1202 protected void installDefaults()
1204 internalFrameLayout
= createLayoutManager();
1205 frame
.setLayout(internalFrameLayout
);
1206 LookAndFeel
.installBorder(frame
, "InternalFrame.border");
1207 frame
.setFrameIcon(UIManager
.getIcon("InternalFrame.icon"));
1208 // InternalFrames are invisible by default.
1209 frame
.setVisible(false);
1213 * This method installs the keyboard actions for the JInternalFrame.
1215 protected void installKeyboardActions()
1217 // FIXME: Implement.
1221 * This method installs the Components for the JInternalFrame.
1223 protected void installComponents()
1225 setNorthPane(createNorthPane(frame
));
1226 setSouthPane(createSouthPane(frame
));
1227 setEastPane(createEastPane(frame
));
1228 setWestPane(createWestPane(frame
));
1232 * This method installs the listeners for the JInternalFrame.
1234 protected void installListeners()
1236 glassPaneDispatcher
= createGlassPaneDispatcher();
1237 createInternalFrameListener();
1238 borderListener
= createBorderListener(frame
);
1239 componentListener
= createComponentListener();
1240 propertyChangeListener
= createPropertyChangeListener();
1241 internalFrameVetoableChangeListener
= new InternalFramePropertyChangeListener();
1243 frame
.addMouseListener(borderListener
);
1244 frame
.addMouseMotionListener(borderListener
);
1245 frame
.addInternalFrameListener(internalFrameListener
);
1246 frame
.addPropertyChangeListener(propertyChangeListener
);
1247 frame
.addVetoableChangeListener(internalFrameVetoableChangeListener
);
1248 frame
.getRootPane().getGlassPane().addMouseListener(glassPaneDispatcher
);
1249 frame
.getRootPane().getGlassPane().addMouseMotionListener(glassPaneDispatcher
);
1253 * This method uninstalls the defaults for the JInternalFrame.
1255 protected void uninstallDefaults()
1257 frame
.setBorder(null);
1258 frame
.setLayout(null);
1259 internalFrameLayout
= null;
1263 * This method uninstalls the Components for the JInternalFrame.
1265 protected void uninstallComponents()
1274 * This method uninstalls the listeners for the JInternalFrame.
1276 protected void uninstallListeners()
1278 if (desktopPane
!= null)
1279 desktopPane
.removeComponentListener(componentListener
);
1281 frame
.getRootPane().getGlassPane().removeMouseMotionListener(glassPaneDispatcher
);
1282 frame
.getRootPane().getGlassPane().removeMouseListener(glassPaneDispatcher
);
1284 frame
.removePropertyChangeListener(propertyChangeListener
);
1285 frame
.removeInternalFrameListener(internalFrameListener
);
1286 frame
.removeMouseMotionListener(borderListener
);
1287 frame
.removeMouseListener(borderListener
);
1289 propertyChangeListener
= null;
1290 componentListener
= null;
1291 borderListener
= null;
1292 internalFrameListener
= null;
1293 glassPaneDispatcher
= null;
1297 * This method uninstalls the keyboard actions for the JInternalFrame.
1299 protected void uninstallKeyboardActions()
1301 // FIXME: Implement.
1305 * This method creates a new LayoutManager for the JInternalFrame.
1307 * @return A new LayoutManager for the JInternalFrame.
1309 protected LayoutManager
createLayoutManager()
1311 return new InternalFrameLayout();
1315 * This method creates a new PropertyChangeListener for the JInternalFrame.
1317 * @return A new PropertyChangeListener for the JInternalFrame.
1319 protected PropertyChangeListener
createPropertyChangeListener()
1321 return new InternalFramePropertyChangeListener();
1325 * This method returns the preferred size of the given JComponent.
1327 * @param x The JComponent to find a preferred size for.
1329 * @return The preferred size.
1331 public Dimension
getPreferredSize(JComponent x
)
1333 Dimension pref
= null;
1334 LayoutManager layout
= frame
.getLayout();
1335 if (frame
== x
&& layout
!= null)
1336 pref
= layout
.preferredLayoutSize(frame
);
1338 pref
= new Dimension(100, 100);
1343 * This method returns the minimum size of the given JComponent.
1345 * @param x The JComponent to find a minimum size for.
1347 * @return The minimum size.
1349 public Dimension
getMinimumSize(JComponent x
)
1351 Dimension min
= null;
1352 LayoutManager layout
= frame
.getLayout();
1353 if (frame
== x
&& layout
!= null)
1354 min
= layout
.minimumLayoutSize(frame
);
1356 min
= new Dimension(0, 0);
1361 * This method returns the maximum size of the given JComponent.
1363 * @param x The JComponent to find a maximum size for.
1365 * @return The maximum size.
1367 public Dimension
getMaximumSize(JComponent x
)
1369 Dimension max
= null;
1370 LayoutManager layout
= frame
.getLayout();
1371 if (frame
== x
&& layout
!= null && layout
instanceof LayoutManager2
)
1372 max
= ((LayoutManager2
) layout
).maximumLayoutSize(frame
);
1374 max
= new Dimension(Integer
.MAX_VALUE
, Integer
.MAX_VALUE
);
1379 * This method replaces the currentPane with the newPane. When replacing it
1380 * also removes the MouseHandlers for the old pane and installs them on
1383 * @param currentPane The old pane to remove.
1384 * @param newPane The new pane to install.
1386 protected void replacePane(JComponent currentPane
, JComponent newPane
)
1388 if (currentPane
!= null)
1390 deinstallMouseHandlers(currentPane
);
1391 frame
.remove(currentPane
);
1394 if (newPane
!= null)
1396 installMouseHandlers(newPane
);
1402 * This method removes the necessary MouseListeners from the given
1405 * @param c The JComponent to remove MouseListeners from.
1407 protected void deinstallMouseHandlers(JComponent c
)
1409 c
.removeMouseListener(borderListener
);
1410 c
.removeMouseMotionListener(borderListener
);
1414 * This method installs the necessary MouseListeners from the given
1417 * @param c The JComponent to install MouseListeners on.
1419 protected void installMouseHandlers(JComponent c
)
1421 c
.addMouseListener(borderListener
);
1422 c
.addMouseMotionListener(borderListener
);
1426 * This method creates the north pane used in the JInternalFrame.
1428 * @param w The JInternalFrame to create a north pane for.
1430 * @return The north pane.
1432 protected JComponent
createNorthPane(JInternalFrame w
)
1434 titlePane
= new BasicInternalFrameTitlePane(w
);
1439 * This method creates the west pane used in the JInternalFrame.
1441 * @param w The JInternalFrame to create a west pane for.
1443 * @return The west pane.
1445 protected JComponent
createWestPane(JInternalFrame w
)
1451 * This method creates the south pane used in the JInternalFrame.
1453 * @param w The JInternalFrame to create a south pane for.
1455 * @return The south pane.
1457 protected JComponent
createSouthPane(JInternalFrame w
)
1463 * This method creates the east pane used in the JInternalFrame.
1465 * @param w The JInternalFrame to create an east pane for.
1467 * @return The east pane.
1469 protected JComponent
createEastPane(JInternalFrame w
)
1475 * This method returns a new BorderListener for the given JInternalFrame.
1477 * @param w The JIntenalFrame to create a BorderListener for.
1479 * @return A new BorderListener.
1481 protected MouseInputAdapter
createBorderListener(JInternalFrame w
)
1483 return new BorderListener();
1487 * This method creates a new InternalFrameListener for the JInternalFrame.
1489 protected void createInternalFrameListener()
1491 internalFrameListener
= new BasicInternalFrameListener();
1497 * @return DOCUMENT ME!
1499 protected final boolean isKeyBindingRegistered()
1501 // FIXME: Implement.
1508 * @param b DOCUMENT ME!
1510 protected final void setKeyBindingRegistered(boolean b
)
1512 // FIXME: Implement.
1518 * @return DOCUMENT ME!
1520 public final boolean isKeyBindingActive()
1522 // FIXME: Implement.
1529 * @param b DOCUMENT ME!
1531 protected final void setKeyBindingActive(boolean b
)
1533 // FIXME: Implement.
1539 protected void setupMenuOpenKey()
1541 // FIXME: Implement.
1547 protected void setupMenuCloseKey()
1549 // FIXME: Implement.
1553 * This method returns the north pane.
1555 * @return The north pane.
1557 public JComponent
getNorthPane()
1563 * This method sets the north pane to be the given JComponent.
1565 * @param c The new north pane.
1567 public void setNorthPane(JComponent c
)
1569 replacePane(northPane
, c
);
1574 * This method returns the south pane.
1576 * @return The south pane.
1578 public JComponent
getSouthPane()
1584 * This method sets the south pane to be the given JComponent.
1586 * @param c The new south pane.
1588 public void setSouthPane(JComponent c
)
1590 replacePane(southPane
, c
);
1595 * This method sets the east pane to be the given JComponent.
1597 * @param c The new east pane.
1599 public void setEastPane(JComponent c
)
1601 replacePane(eastPane
, c
);
1606 * This method returns the east pane.
1608 * @return The east pane.
1610 public JComponent
getEastPane()
1616 * This method sets the west pane to be the given JComponent.
1618 * @param c The new west pane.
1620 public void setWestPane(JComponent c
)
1622 replacePane(westPane
, c
);
1627 * This method returns the west pane.
1629 * @return The west pane.
1631 public JComponent
getWestPane()
1637 * This method returns the DesktopManager to use with the JInternalFrame.
1639 * @return The DesktopManager to use with the JInternalFrame.
1641 protected DesktopManager
getDesktopManager()
1643 DesktopManager value
= null;
1644 JDesktopPane pane
= frame
.getDesktopPane();
1646 value
= frame
.getDesktopPane().getDesktopManager();
1648 value
= createDesktopManager();
1653 * This method returns a default DesktopManager that can be used with this
1656 * @return A default DesktopManager that can be used with this
1659 protected DesktopManager
createDesktopManager()
1661 return new DefaultDesktopManager();
1665 * This is a convenience method that closes the JInternalFrame.
1667 * @param f The JInternalFrame to close.
1669 protected void closeFrame(JInternalFrame f
)
1671 getDesktopManager().closeFrame(f
);
1675 * This is a convenience method that maximizes the JInternalFrame.
1677 * @param f The JInternalFrame to maximize.
1679 protected void maximizeFrame(JInternalFrame f
)
1681 getDesktopManager().maximizeFrame(f
);
1685 * This is a convenience method that minimizes the JInternalFrame.
1687 * @param f The JInternalFrame to minimize.
1689 protected void minimizeFrame(JInternalFrame f
)
1691 getDesktopManager().minimizeFrame(f
);
1695 * This is a convenience method that iconifies the JInternalFrame.
1697 * @param f The JInternalFrame to iconify.
1699 protected void iconifyFrame(JInternalFrame f
)
1701 getDesktopManager().iconifyFrame(f
);
1705 * This is a convenience method that deiconifies the JInternalFrame.
1707 * @param f The JInternalFrame to deiconify.
1709 protected void deiconifyFrame(JInternalFrame f
)
1711 getDesktopManager().deiconifyFrame(f
);
1715 * This is a convenience method that activates the JInternalFrame.
1717 * @param f The JInternalFrame to activate.
1719 protected void activateFrame(JInternalFrame f
)
1721 getDesktopManager().activateFrame(f
);
1725 * This is a convenience method that deactivates the JInternalFrame.
1727 * @param f the JInternalFrame to deactivate
1729 protected void deactivateFrame(JInternalFrame f
)
1731 getDesktopManager().deactivateFrame(f
);
1735 * This method returns a new ComponentListener for the JDesktopPane.
1737 * @return A new ComponentListener.
1739 protected ComponentListener
createComponentListener()
1741 return new ComponentHandler();
1745 * This method returns a new GlassPaneDispatcher.
1747 * @return A new GlassPaneDispatcher.
1749 protected MouseInputListener
createGlassPaneDispatcher()
1751 return new GlassPaneDispatcher();