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
;
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
;
78 * This is the UI delegate for the Basic look and feel for JInternalFrames.
80 public class BasicInternalFrameUI
extends InternalFrameUI
83 * This is a helper class that listens to the JInternalFrame for
84 * InternalFrameEvents.
86 protected class BasicInternalFrameListener
implements InternalFrameListener
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);
99 * This method is called when the JInternalFrame is closed.
101 * @param e The InternalFrameEvent.
103 public void internalFrameClosed(InternalFrameEvent e
)
109 * This method is called when the JInternalFrame is closing.
111 * @param e The InternalFrameEvent.
113 public void internalFrameClosing(InternalFrameEvent e
)
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
)
139 * This method is called when the JInternalFrame is iconified.
141 * @param e The InternalFrameEvent.
143 public void internalFrameIconified(InternalFrameEvent e
)
149 * This method is called when the JInternalFrame is opened.
151 * @param e The InternalFrameEvent.
153 public void internalFrameOpened(InternalFrameEvent e
)
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
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())
205 DesktopManager dm
= getDesktopManager();
206 Rectangle b
= frame
.getBounds();
207 Dimension min
= frame
.getMinimumSize();
209 min
= new Dimension(0, 0);
210 Insets insets
= frame
.getInsets();
213 if (e
.getSource() == frame
&& frame
.isResizable())
218 cacheRect
.setBounds(b
.x
, Math
.min(b
.y
+ y
, b
.y
+ b
.height
220 b
.width
, b
.height
- y
);
223 cacheRect
.setBounds(b
.x
, Math
.min(b
.y
+ y
, b
.y
+ b
.height
228 cacheRect
.setBounds(b
.x
, b
.y
, x
, b
.height
);
231 cacheRect
.setBounds(b
.x
, b
.y
, x
, y
);
234 cacheRect
.setBounds(b
.x
, b
.y
, b
.width
, y
);
237 cacheRect
.setBounds(Math
.min(b
.x
+ x
, b
.x
+ b
.width
- min
.width
),
238 b
.y
, b
.width
- x
, y
);
241 cacheRect
.setBounds(Math
.min(b
.x
+ x
, b
.x
+ b
.width
- min
.width
),
242 b
.y
, b
.width
- x
, b
.height
);
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
);
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
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
276 * This method is called when the mouse is moved inside the
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();
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();
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
)
347 else if (x
> b
.width
- insets
.right
&& y
< insets
.top
)
349 else if (x
> b
.width
- insets
.right
&& y
> b
.height
- insets
.bottom
)
351 else if (x
< insets
.left
&& y
> b
.height
- insets
.bottom
)
353 else if (y
< insets
.top
)
355 else if (x
< insets
.left
)
357 else if (y
> b
.height
- insets
.bottom
)
359 else if (x
> b
.width
- insets
.right
)
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.
377 * The ComponentEvent fired.
379 public void componentHidden(ComponentEvent e
)
385 * This method is called when the JDesktopPane is moved.
388 * The ComponentEvent fired.
390 public void componentMoved(ComponentEvent e
)
396 * This method is called when the JDesktopPane is resized.
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
);
416 // Sun also resizes the icons. but it doesn't seem to do anything.
420 * This method is called when the JDesktopPane is shown.
423 * The ComponentEvent fired.
425 public void componentShown(ComponentEvent e
)
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
441 * The name of the Component.
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
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
;
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
,
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
,
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.
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.
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);
543 * @return DOCUMENT ME!
545 private Dimension
getSize(Container c
, boolean min
)
547 Insets insets
= frame
.getInsets();
549 Dimension contentDims
= frame
.getContentPane().getPreferredSize();
551 contentDims
.width
= contentDims
.height
= 0;
562 if (northPane
!= null)
564 dims
= northPane
.getPreferredSize();
568 nHeight
= dims
.height
;
572 if (southPane
!= null)
574 dims
= southPane
.getPreferredSize();
578 sHeight
= dims
.height
;
582 if (eastPane
!= null)
584 dims
= eastPane
.getPreferredSize();
588 sHeight
= dims
.height
;
592 if (westPane
!= null)
594 dims
= westPane
.getPreferredSize();
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
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.
655 public void mouseEntered(MouseEvent e
)
661 * This method is called when the mouse is clicked on the glass pane.
666 public void mouseClicked(MouseEvent e
)
672 * This method is called when the mouse is dragged in the glass pane.
677 public void mouseDragged(MouseEvent e
)
683 * This method is called when the mouse exits the glass pane.
688 public void mouseExited(MouseEvent e
)
694 * This method is called when the mouse is moved in the glass pane.
699 public void mouseMoved(MouseEvent e
)
705 * This method is called when the mouse is pressed in the glass pane.
710 public void mousePressed(MouseEvent e
)
712 activateFrame(frame
);
717 * This method is called when the mouse is released in the glass pane.
722 public void mouseReleased(MouseEvent e
)
728 * This method acquires a candidate component to dispatch the MouseEvent to.
731 * The MouseEvent to acquire a component for.
733 private void acquireComponentForMouseEvent(MouseEvent me
)
738 // Find the candidate which should receive this event.
739 Component parent
= frame
.getLayeredPane();
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
,
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
758 if (candidate
== frame
.getContentPane())
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(),
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
,
792 me
.getModifiersEx(), cp
.x
,
793 cp
.y
, me
.getClickCount(),
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:
807 // - MOUSE_PRESSED: another button pressed while the first is held down
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
826 * The AWTEvent to be dispatched. Usually an instance of
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)
840 //Avoid re-dispatching to ourselves and causing an infinite loop
841 if (mouseEventTarget
.equals(frame
.getGlassPane()))
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(),
853 mouseEventTarget
.dispatchEvent(newEvt
);
857 case MouseEvent
.MOUSE_PRESSED
:
858 if (pressCount
++ == 0)
859 pressedComponent
= mouseEventTarget
;
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;
875 * This helper class listens for PropertyChangeEvents from the
878 public class InternalFramePropertyChangeListener
879 implements PropertyChangeListener
883 * This method is called when one of the JInternalFrame's properties change.
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
);
895 minimizeFrame(frame
);
897 else if (evt
.getPropertyName().equals(JInternalFrame
.IS_ICON_PROPERTY
))
902 deiconifyFrame(frame
);
904 else if (evt
.getPropertyName().equals(JInternalFrame
.IS_SELECTED_PROPERTY
))
906 if (frame
.isSelected())
907 activateFrame(frame
);
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
);
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
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()
959 * This method returns the insets of the border.
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.
974 * The Component that owns the border.
976 * The Graphics object to paint with.
978 * The x coordinate to paint at.
980 * The y coordinate to paint at.
982 * The width of the Component.
984 * The height of the Component.
986 public void paintBorder(Component c
, Graphics g
, int x
, int y
, int width
,
990 Color saved
= g
.getColor();
991 Rectangle b
= frame
.getBounds();
993 Color d
= c
.getBackground();
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
);
1002 int x3
= b
.width
- bSize
;
1007 int y3
= b
.height
- bSize
;
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
);
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.
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
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
;
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);
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);
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()
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
);
1284 pref
= new Dimension(100, 100);
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
);
1302 min
= new Dimension(0, 0);
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
);
1320 max
= new Dimension(Integer
.MAX_VALUE
, Integer
.MAX_VALUE
);
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
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
);
1348 * This method removes the necessary MouseListeners from the given
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
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
);
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
)
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
)
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
)
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();
1443 * @return DOCUMENT ME!
1445 protected final boolean isKeyBindingRegistered()
1447 // FIXME: Implement.
1454 * @param b DOCUMENT ME!
1456 protected final void setKeyBindingRegistered(boolean b
)
1458 // FIXME: Implement.
1464 * @return DOCUMENT ME!
1466 public final boolean isKeyBindingActive()
1468 // FIXME: Implement.
1475 * @param b DOCUMENT ME!
1477 protected final void setKeyBindingActive(boolean b
)
1479 // FIXME: Implement.
1485 protected void setupMenuOpenKey()
1487 // FIXME: Implement.
1493 protected void setupMenuCloseKey()
1495 // FIXME: Implement.
1499 * This method returns the north pane.
1501 * @return The north pane.
1503 public JComponent
getNorthPane()
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
);
1520 * This method returns the south pane.
1522 * @return The south pane.
1524 public JComponent
getSouthPane()
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
);
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
);
1552 * This method returns the east pane.
1554 * @return The east pane.
1556 public JComponent
getEastPane()
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
);
1573 * This method returns the west pane.
1575 * @return The west pane.
1577 public JComponent
getWestPane()
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();
1592 value
= frame
.getDesktopPane().getDesktopManager();
1594 value
= createDesktopManager();
1599 * This method returns a default DesktopManager that can be used with this
1602 * @return A default DesktopManager that can be used with this
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();