summaryrefslogtreecommitdiff
path: root/libjava/javax/swing/plaf/basic/BasicInternalFrameUI.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/javax/swing/plaf/basic/BasicInternalFrameUI.java')
-rw-r--r--libjava/javax/swing/plaf/basic/BasicInternalFrameUI.java232
1 files changed, 200 insertions, 32 deletions
diff --git a/libjava/javax/swing/plaf/basic/BasicInternalFrameUI.java b/libjava/javax/swing/plaf/basic/BasicInternalFrameUI.java
index 5c598b763ce..d394b951b7e 100644
--- a/libjava/javax/swing/plaf/basic/BasicInternalFrameUI.java
+++ b/libjava/javax/swing/plaf/basic/BasicInternalFrameUI.java
@@ -37,6 +37,7 @@ exception statement from your version. */
package javax.swing.plaf.basic;
+import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
@@ -179,6 +180,9 @@ public class BasicInternalFrameUI extends InternalFrameUI
/** The direction that the resize is occuring in. */
private transient int direction = -1;
+ /** Cache rectangle that can be reused. */
+ private transient Rectangle cacheRect = new Rectangle();
+
/**
* This method is called when the mouse is clicked.
*
@@ -204,6 +208,9 @@ public class BasicInternalFrameUI extends InternalFrameUI
return;
DesktopManager dm = getDesktopManager();
Rectangle b = frame.getBounds();
+ Dimension min = frame.getMinimumSize();
+ if (min == null)
+ min = new Dimension(0, 0);
Insets insets = frame.getInsets();
int x = e.getX();
int y = e.getY();
@@ -212,31 +219,43 @@ public class BasicInternalFrameUI extends InternalFrameUI
switch (direction)
{
case NORTH:
- dm.resizeFrame(frame, b.x, b.y + y, b.width, b.height - y);
+ cacheRect.setBounds(b.x,
+ Math.min(b.y + y, b.y + b.height
+ - min.height), b.width, b.height
+ - y);
break;
case NORTH_EAST:
- dm.resizeFrame(frame, b.x, b.y + y, x, b.height - y);
+ cacheRect.setBounds(b.x,
+ Math.min(b.y + y, b.y + b.height
+ - min.height), x, b.height - y);
break;
case EAST:
- dm.resizeFrame(frame, b.x, b.y, x, b.height);
+ cacheRect.setBounds(b.x, b.y, x, b.height);
break;
case SOUTH_EAST:
- dm.resizeFrame(frame, b.x, b.y, x, y);
+ cacheRect.setBounds(b.x, b.y, x, y);
break;
case SOUTH:
- dm.resizeFrame(frame, b.x, b.y, b.width, y);
+ cacheRect.setBounds(b.x, b.y, b.width, y);
break;
case SOUTH_WEST:
- dm.resizeFrame(frame, b.x + x, b.y, b.width - x, y);
+ cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
+ b.y, b.width - x, y);
break;
case WEST:
- dm.resizeFrame(frame, b.x + x, b.y, b.width - x, b.height);
+ cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
+ b.y, b.width - x, b.height);
break;
case NORTH_WEST:
- dm.resizeFrame(frame, b.x + x, b.y + y, b.width - x, b.height
- - y);
+ cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
+ Math.min(b.y + y, b.y + b.height
+ - min.height), b.width - x,
+ b.height - y);
break;
}
+ dm.resizeFrame(frame, cacheRect.x, cacheRect.y,
+ Math.max(min.width, cacheRect.width),
+ Math.max(min.height, cacheRect.height));
}
else if (e.getSource() == titlePane)
{
@@ -498,7 +517,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public Dimension minimumLayoutSize(Container c)
{
- return preferredLayoutSize(c);
+ return getSize(c, true);
}
/**
@@ -522,9 +541,24 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public Dimension preferredLayoutSize(Container c)
{
+ return getSize(c, false);
+ }
+
+ /**
+ * DOCUMENT ME!
+ *
+ * @param c DOCUMENT ME!
+ * @param min DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ private Dimension getSize(Container c, boolean min)
+ {
Insets insets = frame.getInsets();
Dimension contentDims = frame.getContentPane().getPreferredSize();
+ if (min)
+ contentDims.width = contentDims.height = 0;
int nWidth = 0;
int nHeight = 0;
int sWidth = 0;
@@ -578,8 +612,8 @@ public class BasicInternalFrameUI extends InternalFrameUI
int width = Math.max(sWidth, nWidth);
width = Math.max(width, contentDims.width + eWidth + wWidth);
- int height = Math.max(contentDims.height, eHeight);
- height = Math.max(height, wHeight);
+ int height = Math.max(eHeight, wHeight);
+ height = Math.max(height, contentDims.height);
height += nHeight + sHeight;
width += insets.left + insets.right;
@@ -606,6 +640,18 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
protected class GlassPaneDispatcher implements MouseInputListener
{
+ /** The MouseEvent target. */
+ private transient Component mouseEventTarget;
+
+ /** The component pressed. */
+ private transient Component pressedComponent;
+
+ /** The last component entered. */
+ private transient Component lastComponentEntered;
+
+ /** The number of presses. */
+ private transient int pressCount;
+
/**
* This method is called when the mouse enters the glass pane.
*
@@ -613,7 +659,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void mouseEntered(MouseEvent e)
{
- dispatchFor(e);
+ handleEvent(e);
}
/**
@@ -623,7 +669,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void mouseClicked(MouseEvent e)
{
- dispatchFor(e);
+ handleEvent(e);
}
/**
@@ -633,7 +679,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void mouseDragged(MouseEvent e)
{
- dispatchFor(e);
+ handleEvent(e);
}
/**
@@ -643,7 +689,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void mouseExited(MouseEvent e)
{
- dispatchFor(e);
+ handleEvent(e);
}
/**
@@ -653,7 +699,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void mouseMoved(MouseEvent e)
{
- dispatchFor(e);
+ handleEvent(e);
}
/**
@@ -664,7 +710,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
public void mousePressed(MouseEvent e)
{
activateFrame(frame);
- dispatchFor(e);
+ handleEvent(e);
}
/**
@@ -674,27 +720,149 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public void mouseReleased(MouseEvent e)
{
- dispatchFor(e);
+ handleEvent(e);
}
/**
- * This helper method redispatches the MouseEvent to the proper sub
- * component.
+ * This method acquires a candidate component to dispatch the MouseEvent
+ * to.
*
- * @param e The MouseEvent.
+ * @param me The MouseEvent to acquire a component for.
*/
- private void dispatchFor(MouseEvent e)
+ private void acquireComponentForMouseEvent(MouseEvent me)
{
- Component candidate = SwingUtilities.getDeepestComponentAt(frame.getRootPane()
- .getContentPane(),
- e.getX(),
- e.getY());
- if (candidate == null || candidate == frame.getRootPane().getGlassPane())
+ int x = me.getX();
+ int y = me.getY();
+
+ // Find the candidate which should receive this event.
+ Component parent = frame.getContentPane();
+ if (parent == null)
return;
- MouseEvent newevt = SwingUtilities.convertMouseEvent(frame.getRootPane()
+ Component candidate = null;
+ Point p = me.getPoint();
+ while (candidate == null && parent != null)
+ {
+ candidate = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y);
+ if (candidate == null)
+ {
+ p = SwingUtilities.convertPoint(parent, p.x, p.y,
+ parent.getParent());
+ parent = parent.getParent();
+ }
+ }
+
+ // If the only candidate we found was the native container itself,
+ // don't dispatch any event at all. We only care about the lightweight
+ // children here.
+ if (candidate == frame.getContentPane())
+ candidate = null;
+
+ // If our candidate is new, inform the old target we're leaving.
+ if (lastComponentEntered != null && lastComponentEntered.isShowing()
+ && lastComponentEntered != candidate)
+ {
+ Point tp = SwingUtilities.convertPoint(frame.getContentPane(), x, y,
+ lastComponentEntered);
+ MouseEvent exited = new MouseEvent(lastComponentEntered,
+ MouseEvent.MOUSE_EXITED,
+ me.getWhen(), me.getModifiers(),
+ tp.x, tp.y, me.getClickCount(),
+ me.isPopupTrigger(),
+ me.getButton());
+ lastComponentEntered.dispatchEvent(exited);
+ lastComponentEntered = null;
+ }
+
+ // If we have a candidate, maybe enter it.
+ if (candidate != null)
+ {
+ mouseEventTarget = candidate;
+ if (candidate.isLightweight() && candidate.isShowing()
+ && candidate != frame.getContentPane()
+ && candidate != lastComponentEntered)
+ {
+ lastComponentEntered = mouseEventTarget;
+ Point cp = SwingUtilities.convertPoint(frame.getContentPane(),
+ x, y, lastComponentEntered);
+ MouseEvent entered = new MouseEvent(lastComponentEntered,
+ MouseEvent.MOUSE_ENTERED,
+ me.getWhen(),
+ me.getModifiers(), cp.x,
+ cp.y, me.getClickCount(),
+ me.isPopupTrigger(),
+ me.getButton());
+ lastComponentEntered.dispatchEvent(entered);
+ }
+ }
+
+ if (me.getID() == MouseEvent.MOUSE_RELEASED
+ || me.getID() == MouseEvent.MOUSE_PRESSED && pressCount > 0
+ || me.getID() == MouseEvent.MOUSE_DRAGGED)
+ // If any of the following events occur while a button is held down,
+ // they should be dispatched to the same component to which the
+ // original MOUSE_PRESSED event was dispatched:
+ // - MOUSE_RELEASED
+ // - MOUSE_PRESSED: another button pressed while the first is held down
+ // - MOUSE_DRAGGED
+ mouseEventTarget = pressedComponent;
+ else if (me.getID() == MouseEvent.MOUSE_CLICKED)
+ {
+ // Don't dispatch CLICKED events whose target is not the same as the
+ // target for the original PRESSED event.
+ if (candidate != pressedComponent)
+ mouseEventTarget = null;
+ else if (pressCount == 0)
+ pressedComponent = null;
+ }
+ }
+
+ /**
+ * This is a helper method that dispatches the GlassPane MouseEvents to
+ * the proper component.
+ *
+ * @param e The AWTEvent to be dispatched. Usually an instance of
+ * MouseEvent.
+ */
+ private void handleEvent(AWTEvent e)
+ {
+ if (e instanceof MouseEvent)
+ {
+ MouseEvent me = SwingUtilities.convertMouseEvent(frame.getRootPane()
.getGlassPane(),
- e, candidate);
- candidate.dispatchEvent(newevt);
+ (MouseEvent) e,
+ frame.getRootPane()
+ .getGlassPane());
+
+ acquireComponentForMouseEvent(me);
+
+ // Avoid dispatching ENTERED and EXITED events twice.
+ if (mouseEventTarget != null && mouseEventTarget.isShowing()
+ && e.getID() != MouseEvent.MOUSE_ENTERED
+ && e.getID() != MouseEvent.MOUSE_EXITED)
+ {
+ MouseEvent newEvt = SwingUtilities.convertMouseEvent(frame
+ .getContentPane(),
+ me,
+ mouseEventTarget);
+ mouseEventTarget.dispatchEvent(newEvt);
+
+ switch (e.getID())
+ {
+ case MouseEvent.MOUSE_PRESSED:
+ if (pressCount++ == 0)
+ pressedComponent = mouseEventTarget;
+ break;
+ case MouseEvent.MOUSE_RELEASED:
+ // Clear our memory of the original PRESSED event, only if
+ // we're not expecting a CLICKED event after this. If
+ // there is a CLICKED event after this, it will do clean up.
+ if (--pressCount == 0
+ && mouseEventTarget != pressedComponent)
+ pressedComponent = null;
+ break;
+ }
+ }
+ }
}
}
@@ -1108,7 +1276,7 @@ public class BasicInternalFrameUI extends InternalFrameUI
*/
public Dimension getMinimumSize(JComponent x)
{
- return getPreferredSize(x);
+ return internalFrameLayout.minimumLayoutSize(x);
}
/**