BasicInternalFrameUI.java [plain text]
package javax.swing.plaf.basic;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.DefaultDesktopManager;
import javax.swing.DesktopManager;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JInternalFrame;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.AbstractBorder;
import javax.swing.event.InternalFrameEvent;
import javax.swing.event.InternalFrameListener;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.InternalFrameUI;
import javax.swing.plaf.UIResource;
public class BasicInternalFrameUI extends InternalFrameUI
{
protected class BasicInternalFrameListener implements InternalFrameListener
{
public void internalFrameActivated(InternalFrameEvent e)
{
}
public void internalFrameClosed(InternalFrameEvent e)
{
}
public void internalFrameClosing(InternalFrameEvent e)
{
}
public void internalFrameDeactivated(InternalFrameEvent e)
{
}
public void internalFrameDeiconified(InternalFrameEvent e)
{
}
public void internalFrameIconified(InternalFrameEvent e)
{
}
public void internalFrameOpened(InternalFrameEvent e)
{
}
}
protected class BorderListener extends MouseInputAdapter
implements SwingConstants
{
protected int RESIZE_NONE;
private transient int xOffset = 0;
private transient int yOffset = 0;
private transient int direction = -1;
private transient Rectangle cacheRect = new Rectangle();
public void mouseClicked(MouseEvent e)
{
}
public void mouseDragged(MouseEvent e)
{
if (frame.isMaximum())
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();
if (e.getSource() == frame && frame.isResizable())
{
switch (direction)
{
case NORTH:
cacheRect.setBounds(b.x,
Math.min(b.y + y, b.y + b.height
- min.height), b.width, b.height
- y);
break;
case NORTH_EAST:
cacheRect.setBounds(b.x,
Math.min(b.y + y, b.y + b.height
- min.height), x, b.height - y);
break;
case EAST:
cacheRect.setBounds(b.x, b.y, x, b.height);
break;
case SOUTH_EAST:
cacheRect.setBounds(b.x, b.y, x, y);
break;
case SOUTH:
cacheRect.setBounds(b.x, b.y, b.width, y);
break;
case SOUTH_WEST:
cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
b.y, b.width - x, y);
break;
case WEST:
cacheRect.setBounds(Math.min(b.x + x, b.x + b.width - min.width),
b.y, b.width - x, b.height);
break;
case NORTH_WEST:
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)
{
Rectangle fBounds = frame.getBounds();
dm.dragFrame(frame, e.getX() - xOffset + b.x,
e.getY() - yOffset + b.y);
}
}
public void mouseExited(MouseEvent e)
{
}
public void mouseMoved(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
activateFrame(frame);
DesktopManager dm = getDesktopManager();
int x = e.getX();
int y = e.getY();
Insets insets = frame.getInsets();
if (e.getSource() == frame && frame.isResizable())
{
direction = sectionOfClick(x, y);
dm.beginResizingFrame(frame, direction);
}
else if (e.getSource() == titlePane)
{
Rectangle tBounds = titlePane.getBounds();
xOffset = e.getX() - tBounds.x + insets.left;
yOffset = e.getY() - tBounds.y + insets.top;
dm.beginDraggingFrame(frame);
}
}
public void mouseReleased(MouseEvent e)
{
DesktopManager dm = getDesktopManager();
xOffset = 0;
yOffset = 0;
if (e.getSource() == frame && frame.isResizable())
dm.endResizingFrame(frame);
else if (e.getSource() == titlePane)
dm.endDraggingFrame(frame);
}
private int sectionOfClick(int x, int y)
{
Insets insets = frame.getInsets();
Rectangle b = frame.getBounds();
if (x < insets.left && y < insets.top)
return NORTH_WEST;
else if (x > b.width - insets.right && y < insets.top)
return NORTH_EAST;
else if (x > b.width - insets.right && y > b.height - insets.bottom)
return SOUTH_EAST;
else if (x < insets.left && y > b.height - insets.bottom)
return SOUTH_WEST;
else if (y < insets.top)
return NORTH;
else if (x < insets.left)
return WEST;
else if (y > b.height - insets.bottom)
return SOUTH;
else if (x > b.width - insets.right)
return EAST;
return -1;
}
}
protected class ComponentHandler implements ComponentListener
{
public void componentHidden(ComponentEvent e)
{
}
public void componentMoved(ComponentEvent e)
{
}
public void componentResized(ComponentEvent e)
{
if (frame.isMaximum())
{
JDesktopPane pane = (JDesktopPane) e.getSource();
Insets insets = pane.getInsets();
Rectangle bounds = pane.getBounds();
frame.setBounds(bounds.x + insets.left, bounds.y + insets.top,
bounds.width - insets.left - insets.right,
bounds.height - insets.top - insets.bottom);
frame.revalidate();
frame.repaint();
}
}
public void componentShown(ComponentEvent e)
{
}
}
public class InternalFrameLayout implements LayoutManager
{
public void addLayoutComponent(String name, Component c)
{
}
public void layoutContainer(Container c)
{
Dimension dims = frame.getSize();
Insets insets = frame.getInsets();
dims.width -= insets.left + insets.right;
dims.height -= insets.top + insets.bottom;
frame.getRootPane().getGlassPane().setBounds(0, 0, dims.width,
dims.height);
int nh = 0;
int sh = 0;
int ew = 0;
int ww = 0;
if (northPane != null)
{
Dimension nDims = northPane.getPreferredSize();
nh = Math.min(nDims.height, dims.height);
northPane.setBounds(insets.left, insets.top, dims.width, nh);
}
if (southPane != null)
{
Dimension sDims = southPane.getPreferredSize();
sh = Math.min(sDims.height, dims.height - nh);
southPane.setBounds(insets.left, insets.top + dims.height - sh,
dims.width, sh);
}
int remHeight = dims.height - sh - nh;
if (westPane != null)
{
Dimension wDims = westPane.getPreferredSize();
ww = Math.min(dims.width, wDims.width);
westPane.setBounds(insets.left, insets.top + nh, ww, remHeight);
}
if (eastPane != null)
{
Dimension eDims = eastPane.getPreferredSize();
ew = Math.min(eDims.width, dims.width - ww);
eastPane.setBounds(insets.left + dims.width - ew, insets.top + nh,
ew, remHeight);
}
int remWidth = dims.width - ww - ew;
frame.getRootPane().setBounds(insets.left + ww, insets.top + nh,
remWidth, remHeight);
}
public Dimension minimumLayoutSize(Container c)
{
return getSize(c, true);
}
public Dimension maximumLayoutSize(Container c)
{
return preferredLayoutSize(c);
}
public Dimension preferredLayoutSize(Container c)
{
return getSize(c, false);
}
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;
int sHeight = 0;
int eWidth = 0;
int eHeight = 0;
int wWidth = 0;
int wHeight = 0;
Dimension dims;
if (northPane != null)
{
dims = northPane.getPreferredSize();
if (dims != null)
{
nWidth = dims.width;
nHeight = dims.height;
}
}
if (southPane != null)
{
dims = southPane.getPreferredSize();
if (dims != null)
{
sWidth = dims.width;
sHeight = dims.height;
}
}
if (eastPane != null)
{
dims = eastPane.getPreferredSize();
if (dims != null)
{
sWidth = dims.width;
sHeight = dims.height;
}
}
if (westPane != null)
{
dims = westPane.getPreferredSize();
if (dims != null)
{
wWidth = dims.width;
wHeight = dims.height;
}
}
int width = Math.max(sWidth, nWidth);
width = Math.max(width, contentDims.width + eWidth + wWidth);
int height = Math.max(eHeight, wHeight);
height = Math.max(height, contentDims.height);
height += nHeight + sHeight;
width += insets.left + insets.right;
height += insets.top + insets.bottom;
return new Dimension(width, height);
}
public void removeLayoutComponent(Component c)
{
}
}
protected class GlassPaneDispatcher implements MouseInputListener
{
private transient Component mouseEventTarget;
private transient Component pressedComponent;
private transient Component lastComponentEntered;
private transient int pressCount;
public void mouseEntered(MouseEvent e)
{
handleEvent(e);
}
public void mouseClicked(MouseEvent e)
{
handleEvent(e);
}
public void mouseDragged(MouseEvent e)
{
handleEvent(e);
}
public void mouseExited(MouseEvent e)
{
handleEvent(e);
}
public void mouseMoved(MouseEvent e)
{
handleEvent(e);
}
public void mousePressed(MouseEvent e)
{
activateFrame(frame);
handleEvent(e);
}
public void mouseReleased(MouseEvent e)
{
handleEvent(e);
}
private void acquireComponentForMouseEvent(MouseEvent me)
{
int x = me.getX();
int y = me.getY();
Component parent = frame.getContentPane();
if (parent == null)
return;
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 (candidate == frame.getContentPane())
candidate = null;
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.getModifiersEx(),
tp.x, tp.y, me.getClickCount(),
me.isPopupTrigger(),
me.getButton());
lastComponentEntered.dispatchEvent(exited);
lastComponentEntered = null;
}
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.getModifiersEx(), 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)
mouseEventTarget = pressedComponent;
else if (me.getID() == MouseEvent.MOUSE_CLICKED)
{
if (candidate != pressedComponent)
mouseEventTarget = null;
else if (pressCount == 0)
pressedComponent = null;
}
}
private void handleEvent(AWTEvent e)
{
if (e instanceof MouseEvent)
{
MouseEvent me = SwingUtilities.convertMouseEvent(frame.getRootPane()
.getGlassPane(),
(MouseEvent) e,
frame.getRootPane()
.getGlassPane());
acquireComponentForMouseEvent(me);
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:
if (--pressCount == 0
&& mouseEventTarget != pressedComponent)
pressedComponent = null;
break;
}
}
}
}
}
public class InternalFramePropertyChangeListener
implements PropertyChangeListener
{
public void propertyChange(PropertyChangeEvent evt)
{
if (evt.getPropertyName().equals(JInternalFrame.IS_MAXIMUM_PROPERTY))
{
if (frame.isMaximum())
maximizeFrame(frame);
else
minimizeFrame(frame);
}
else if (evt.getPropertyName().equals(JInternalFrame.IS_CLOSED_PROPERTY))
closeFrame(frame);
else if (evt.getPropertyName().equals(JInternalFrame.IS_ICON_PROPERTY))
{
if (frame.isIcon())
iconifyFrame(frame);
else
deiconifyFrame(frame);
}
else if (evt.getPropertyName().equals(JInternalFrame.IS_SELECTED_PROPERTY))
{
if (frame.isSelected())
activateFrame(frame);
else
getDesktopManager().deactivateFrame(frame);
}
else if (evt.getPropertyName().equals(JInternalFrame.ROOT_PANE_PROPERTY)
|| evt.getPropertyName().equals(JInternalFrame.GLASS_PANE_PROPERTY))
{
Component old = (Component) evt.getOldValue();
old.removeMouseListener(glassPaneDispatcher);
old.removeMouseMotionListener(glassPaneDispatcher);
Component newPane = (Component) evt.getNewValue();
newPane.addMouseListener(glassPaneDispatcher);
newPane.addMouseMotionListener(glassPaneDispatcher);
frame.revalidate();
}
}
}
private class InternalFrameBorder extends AbstractBorder
implements UIResource
{
private static final int bSize = 5;
private static final int offset = 10;
public boolean isBorderOpaque()
{
return true;
}
public Insets getBorderInsets(Component c)
{
return new Insets(bSize, bSize, bSize, bSize);
}
public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height)
{
g.translate(x, y);
Color saved = g.getColor();
Rectangle b = frame.getBounds();
Color d = c.getBackground();
g.setColor(d);
g.fillRect(0, 0, bSize, b.height);
g.fillRect(0, 0, b.width, bSize);
g.fillRect(0, b.height - bSize, b.width, bSize);
g.fillRect(b.width - bSize, 0, bSize, b.height);
int x1 = 0;
int x2 = bSize;
int x3 = b.width - bSize;
int x4 = b.width;
int y1 = 0;
int y2 = bSize;
int y3 = b.height - bSize;
int y4 = b.height;
g.setColor(Color.GRAY);
g.fillRect(0, 0, bSize, y4);
g.fillRect(0, 0, x4, bSize);
g.fillRect(0, y3, b.width, bSize);
g.fillRect(x3, 0, bSize, b.height);
g.fill3DRect(0, offset, bSize, b.height - 2 * offset, false);
g.fill3DRect(offset, 0, b.width - 2 * offset, bSize, false);
g.fill3DRect(offset, b.height - bSize, b.width - 2 * offset, bSize, false);
g.fill3DRect(b.width - bSize, offset, bSize, b.height - 2 * offset, false);
g.translate(-x, -y);
g.setColor(saved);
}
}
protected MouseInputAdapter borderListener;
protected ComponentListener componentListener;
protected MouseInputListener glassPaneDispatcher;
protected PropertyChangeListener propertyChangeListener;
private transient BasicInternalFrameListener internalFrameListener;
protected JComponent eastPane;
protected JComponent northPane;
protected JComponent southPane;
protected JComponent westPane;
protected KeyStroke openMenuKey;
protected BasicInternalFrameTitlePane titlePane;
protected JInternalFrame frame;
protected LayoutManager internalFrameLayout;
private transient JDesktopPane desktopPane;
public BasicInternalFrameUI(JInternalFrame b)
{
}
public static ComponentUI createUI(JComponent b)
{
return new BasicInternalFrameUI((JInternalFrame) b);
}
public void installUI(JComponent c)
{
if (c instanceof JInternalFrame)
{
frame = (JInternalFrame) c;
internalFrameLayout = createLayoutManager();
frame.setLayout(internalFrameLayout);
((JComponent) frame.getRootPane().getGlassPane()).setOpaque(false);
frame.getRootPane().getGlassPane().setVisible(true);
installDefaults();
installListeners();
installComponents();
installKeyboardActions();
frame.setOpaque(true);
titlePane.setOpaque(true);
frame.invalidate();
}
}
public void uninstallUI(JComponent c)
{
uninstallKeyboardActions();
uninstallComponents();
uninstallListeners();
uninstallDefaults();
frame.setLayout(null);
((JComponent) frame.getRootPane().getGlassPane()).setOpaque(true);
frame.getRootPane().getGlassPane().setVisible(false);
frame = null;
}
protected void installDefaults()
{
frame.setBorder(new InternalFrameBorder());
}
protected void installKeyboardActions()
{
}
protected void installComponents()
{
setNorthPane(createNorthPane(frame));
setSouthPane(createSouthPane(frame));
setEastPane(createEastPane(frame));
setWestPane(createWestPane(frame));
}
protected void installListeners()
{
glassPaneDispatcher = createGlassPaneDispatcher();
createInternalFrameListener();
borderListener = createBorderListener(frame);
componentListener = createComponentListener();
propertyChangeListener = createPropertyChangeListener();
frame.addMouseListener(borderListener);
frame.addMouseMotionListener(borderListener);
frame.addInternalFrameListener(internalFrameListener);
frame.addPropertyChangeListener(propertyChangeListener);
frame.getRootPane().getGlassPane().addMouseListener(glassPaneDispatcher);
frame.getRootPane().getGlassPane().addMouseMotionListener(glassPaneDispatcher);
}
protected void uninstallDefaults()
{
frame.setBorder(null);
}
protected void uninstallComponents()
{
setNorthPane(null);
setSouthPane(null);
setEastPane(null);
setWestPane(null);
}
protected void uninstallListeners()
{
if (desktopPane != null)
desktopPane.removeComponentListener(componentListener);
frame.getRootPane().getGlassPane().removeMouseMotionListener(glassPaneDispatcher);
frame.getRootPane().getGlassPane().removeMouseListener(glassPaneDispatcher);
frame.removePropertyChangeListener(propertyChangeListener);
frame.removeInternalFrameListener(internalFrameListener);
frame.removeMouseMotionListener(borderListener);
frame.removeMouseListener(borderListener);
propertyChangeListener = null;
componentListener = null;
borderListener = null;
internalFrameListener = null;
glassPaneDispatcher = null;
}
protected void uninstallKeyboardActions()
{
}
protected LayoutManager createLayoutManager()
{
return new InternalFrameLayout();
}
protected PropertyChangeListener createPropertyChangeListener()
{
return new InternalFramePropertyChangeListener();
}
public Dimension getPreferredSize(JComponent x)
{
return internalFrameLayout.preferredLayoutSize(x);
}
public Dimension getMinimumSize(JComponent x)
{
return internalFrameLayout.minimumLayoutSize(x);
}
public Dimension getMaximumSize(JComponent x)
{
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
}
protected void replacePane(JComponent currentPane, JComponent newPane)
{
if (currentPane != null)
{
deinstallMouseHandlers(currentPane);
frame.remove(currentPane);
}
if (newPane != null)
{
installMouseHandlers(newPane);
frame.add(newPane);
}
}
protected void deinstallMouseHandlers(JComponent c)
{
c.removeMouseListener(borderListener);
c.removeMouseMotionListener(borderListener);
}
protected void installMouseHandlers(JComponent c)
{
c.addMouseListener(borderListener);
c.addMouseMotionListener(borderListener);
}
protected JComponent createNorthPane(JInternalFrame w)
{
titlePane = new BasicInternalFrameTitlePane(w);
return titlePane;
}
protected JComponent createWestPane(JInternalFrame w)
{
return null;
}
protected JComponent createSouthPane(JInternalFrame w)
{
return null;
}
protected JComponent createEastPane(JInternalFrame w)
{
return null;
}
protected MouseInputAdapter createBorderListener(JInternalFrame w)
{
return new BorderListener();
}
protected void createInternalFrameListener()
{
internalFrameListener = new BasicInternalFrameListener();
}
protected final boolean isKeyBindingRegistered()
{
return false;
}
protected final void setKeyBindingRegistered(boolean b)
{
}
public final boolean isKeyBindingActive()
{
return false;
}
protected final void setKeyBindingActive(boolean b)
{
}
protected void setupMenuOpenKey()
{
}
protected void setupMenuCloseKey()
{
}
public JComponent getNorthPane()
{
return northPane;
}
public void setNorthPane(JComponent c)
{
replacePane(northPane, c);
northPane = c;
}
public JComponent getSouthPane()
{
return southPane;
}
public void setSouthPane(JComponent c)
{
replacePane(southPane, c);
southPane = c;
}
public void setEastPane(JComponent c)
{
replacePane(eastPane, c);
eastPane = c;
}
public JComponent getEastPane()
{
return eastPane;
}
public void setWestPane(JComponent c)
{
replacePane(westPane, c);
westPane = c;
}
public JComponent getWestPane()
{
return westPane;
}
protected DesktopManager getDesktopManager()
{
DesktopManager value = frame.getDesktopPane().getDesktopManager();
if (value == null)
value = createDesktopManager();
return value;
}
protected DesktopManager createDesktopManager()
{
return new DefaultDesktopManager();
}
protected void closeFrame(JInternalFrame f)
{
getDesktopManager().closeFrame(f);
}
protected void maximizeFrame(JInternalFrame f)
{
getDesktopManager().maximizeFrame(f);
}
protected void minimizeFrame(JInternalFrame f)
{
getDesktopManager().minimizeFrame(f);
}
protected void iconifyFrame(JInternalFrame f)
{
getDesktopManager().iconifyFrame(f);
}
protected void deiconifyFrame(JInternalFrame f)
{
getDesktopManager().deiconifyFrame(f);
}
protected void activateFrame(JInternalFrame f)
{
getDesktopManager().activateFrame(f);
}
protected ComponentListener createComponentListener()
{
return new ComponentHandler();
}
protected MouseInputListener createGlassPaneDispatcher()
{
return new GlassPaneDispatcher();
}
}