BasicToolBarUI.java [plain text]
package javax.swing.plaf.basic;
import java.awt.BorderLayout;
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.Point;
import java.awt.Rectangle;
import java.awt.Window;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Hashtable;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JToolBar;
import javax.swing.RootPaneContainer;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.BorderUIResource.EtchedBorderUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.ToolBarUI;
import javax.swing.plaf.UIResource;
public class BasicToolBarUI extends ToolBarUI implements SwingConstants
{
private static JFrame owner = new JFrame();
private static Border nonRolloverBorder;
private static Border rolloverBorder;
protected String constraintBeforeFloating;
private int lastGoodOrientation;
protected Color dockingBorderColor;
protected Color dockingColor;
protected MouseInputListener dockingListener;
protected BasicToolBarUI.DragWindow dragWindow;
protected Color floatingBorderColor;
protected Color floatingColor;
protected int focusedCompIndex;
protected PropertyChangeListener propertyListener;
protected JToolBar toolBar;
protected ContainerListener toolBarContListener;
protected FocusListener toolBarFocusListener;
private transient Window floatFrame;
private transient Container origParent;
private transient Hashtable borders;
private transient WindowListener windowListener;
private transient Dimension cachedBounds;
private transient int cachedOrientation;
public BasicToolBarUI()
{
}
public boolean canDock(Component c, Point p)
{
return areaOfClick(c, p) != -1;
}
private int areaOfClick(Component c, Point p)
{
Rectangle pBounds = c.getBounds();
Dimension d = toolBar.getSize();
int limit = Math.min(d.width, d.height);
if (! pBounds.contains(p))
return -1;
if (p.y < limit)
return SwingConstants.NORTH;
if (p.y > (pBounds.height - limit))
return SwingConstants.SOUTH;
if (p.x < limit)
return SwingConstants.WEST;
if (p.x > (pBounds.width - limit))
return SwingConstants.EAST;
return -1;
}
protected MouseInputListener createDockingListener()
{
return new DockingListener(toolBar);
}
protected BasicToolBarUI.DragWindow createDragWindow(JToolBar toolbar)
{
return new DragWindow();
}
protected JFrame createFloatingFrame(JToolBar toolbar)
{
return null;
}
protected RootPaneContainer createFloatingWindow(JToolBar toolbar)
{
return new ToolBarDialog();
}
protected WindowListener createFrameListener()
{
return new FrameListener();
}
protected Border createNonRolloverBorder()
{
return new EtchedBorderUIResource();
}
protected PropertyChangeListener createPropertyListener()
{
return new PropertyListener();
}
protected Border createRolloverBorder()
{
return new EtchedBorderUIResource()
{
public void paintBorder(Component c, Graphics g, int x, int y,
int width, int height)
{
if (c instanceof JButton)
{
if (((JButton) c).getModel().isRollover())
super.paintBorder(c, g, x, y, width, height);
}
}
};
}
protected ContainerListener createToolBarContListener()
{
return new ToolBarContListener();
}
protected FocusListener createToolBarFocusListener()
{
return new ToolBarFocusListener();
}
public static ComponentUI createUI(JComponent c)
{
return new BasicToolBarUI();
}
protected void dragTo(Point position, Point origin)
{
int loc = areaOfClick(origParent,
SwingUtilities.convertPoint(toolBar, position,
origParent));
if (loc != -1)
{
dragWindow.setBorderColor(dockingBorderColor);
dragWindow.setBackground(dockingColor);
}
else
{
dragWindow.setBorderColor(floatingBorderColor);
dragWindow.setBackground(floatingColor);
}
int w = 0;
int h = 0;
boolean tmp = ((loc == SwingConstants.NORTH)
|| (loc == SwingConstants.SOUTH) || (loc == -1));
if (((cachedOrientation == SwingConstants.HORIZONTAL) && tmp)
|| ((cachedOrientation == VERTICAL) && ! tmp))
{
w = cachedBounds.width;
h = cachedBounds.height;
}
else
{
w = cachedBounds.height;
h = cachedBounds.width;
}
Point p = dragWindow.getOffset();
Insets insets = toolBar.getInsets();
dragWindow.setBounds((origin.x + position.x) - p.x
- ((insets.left + insets.right) / 2),
(origin.y + position.y) - p.y
- ((insets.top + insets.bottom) / 2), w, h);
if (! dragWindow.isVisible())
dragWindow.show();
}
protected void floatAt(Point position, Point origin)
{
Point p = new Point(position);
int aoc = areaOfClick(origParent,
SwingUtilities.convertPoint(toolBar, p, origParent));
Container oldParent = toolBar.getParent();
oldParent.remove(toolBar);
oldParent.doLayout();
oldParent.repaint();
Container newParent;
if (aoc == -1)
newParent = ((RootPaneContainer) floatFrame).getContentPane();
else
{
floatFrame.hide();
newParent = origParent;
}
String constraint;
switch (aoc)
{
case SwingConstants.EAST:
constraint = BorderLayout.EAST;
break;
case SwingConstants.NORTH:
constraint = BorderLayout.NORTH;
break;
case SwingConstants.SOUTH:
constraint = BorderLayout.SOUTH;
break;
case SwingConstants.WEST:
constraint = BorderLayout.WEST;
break;
default:
constraint = BorderLayout.CENTER;
break;
}
int newOrientation = SwingConstants.HORIZONTAL;
if ((aoc != -1)
&& ((aoc == SwingConstants.EAST) || (aoc == SwingConstants.WEST)))
newOrientation = SwingConstants.VERTICAL;
if (aoc != -1)
{
constraintBeforeFloating = constraint;
lastGoodOrientation = newOrientation;
}
newParent.add(toolBar, constraint);
setFloating(aoc == -1, null);
toolBar.setOrientation(newOrientation);
Insets insets = floatFrame.getInsets();
Dimension dims = toolBar.getPreferredSize();
p = dragWindow.getOffset();
setFloatingLocation((position.x + origin.x) - p.x
- ((insets.left + insets.right) / 2),
(position.y + origin.y) - p.y
- ((insets.top + insets.bottom) / 2));
if (aoc == -1)
{
floatFrame.pack();
floatFrame.setSize(dims.width + insets.left + insets.right,
dims.height + insets.top + insets.bottom);
floatFrame.show();
}
newParent.invalidate();
newParent.validate();
newParent.repaint();
}
public Color getDockingColor()
{
return dockingColor;
}
public Color getFloatingColor()
{
return floatingColor;
}
public Dimension getMaximumSize(JComponent c)
{
return getPreferredSize(c);
}
public Dimension getMinimumSize(JComponent c)
{
return getPreferredSize(c);
}
public Dimension getPreferredSize(JComponent c)
{
return toolBar.getLayout().preferredLayoutSize(c);
}
protected void installComponents()
{
floatFrame = (Window) createFloatingWindow(toolBar);
dragWindow = createDragWindow(toolBar);
cachedBounds = toolBar.getPreferredSize();
cachedOrientation = toolBar.getOrientation();
nonRolloverBorder = createNonRolloverBorder();
rolloverBorder = createRolloverBorder();
borders = new Hashtable();
fillHashtable();
}
protected void installDefaults()
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
toolBar.setBorder(new ToolBarBorder());
toolBar.setBackground(defaults.getColor("ToolBar.background"));
toolBar.setForeground(defaults.getColor("ToolBar.foreground"));
toolBar.setFont(defaults.getFont("ToolBar.font"));
dockingBorderColor = defaults.getColor("ToolBar.dockingForeground");
dockingColor = defaults.getColor("ToolBar.dockingBackground");
floatingBorderColor = defaults.getColor("ToolBar.floatingForeground");
floatingColor = defaults.getColor("ToolBar.floatingBackground");
}
protected void installKeyboardActions()
{
}
protected void installListeners(JToolBar toolbar)
{
dockingListener = createDockingListener();
toolBar.addMouseListener(dockingListener);
toolBar.addMouseMotionListener(dockingListener);
propertyListener = createPropertyListener();
toolBar.addPropertyChangeListener(propertyListener);
toolBarContListener = createToolBarContListener();
toolBar.addContainerListener(toolBarContListener);
windowListener = createFrameListener();
floatFrame.addWindowListener(windowListener);
toolBarFocusListener = createToolBarFocusListener();
toolBar.addFocusListener(toolBarFocusListener);
}
protected void installNonRolloverBorders(JComponent c)
{
Component[] components = toolBar.getComponents();
for (int i = 0; i < components.length; i++)
setBorderToNonRollover(components[i]);
}
protected void installNormalBorders(JComponent c)
{
Component[] components = toolBar.getComponents();
for (int i = 0; i < components.length; i++)
setBorderToNormal(components[i]);
}
protected void installRolloverBorders(JComponent c)
{
Component[] components = toolBar.getComponents();
for (int i = 0; i < components.length; i++)
setBorderToRollover(components[i]);
}
private void fillHashtable()
{
Component[] c = toolBar.getComponents();
for (int i = 0; i < c.length; i++)
{
if (c[i] instanceof JButton)
{
JButton b = (JButton) c[i];
if (b.getBorder() != null)
borders.put(b, b.getBorder());
}
}
}
public void installUI(JComponent c)
{
super.installUI(c);
if (c instanceof JToolBar)
{
toolBar = (JToolBar) c;
toolBar.setOpaque(true);
installDefaults();
installComponents();
installListeners(toolBar);
installKeyboardActions();
}
}
public boolean isFloating()
{
return floatFrame.isVisible();
}
public boolean isRolloverBorders()
{
return toolBar.isRollover();
}
protected void navigateFocusedComp(int direction)
{
}
protected void setBorderToNonRollover(Component c)
{
if (c instanceof JButton)
{
JButton b = (JButton) c;
b.setRolloverEnabled(false);
b.setBorder(nonRolloverBorder);
}
}
protected void setBorderToNormal(Component c)
{
if (c instanceof JButton)
{
JButton b = (JButton) c;
Border border = (Border) borders.get(b);
b.setBorder(border);
}
}
protected void setBorderToRollover(Component c)
{
if (c instanceof JButton)
{
JButton b = (JButton) c;
b.setRolloverEnabled(true);
b.setBorder(rolloverBorder);
}
}
public void setDockingColor(Color c)
{
dockingColor = c;
}
public void setFloating(boolean b, Point p)
{
floatFrame.setVisible(b);
}
public void setFloatingColor(Color c)
{
floatingColor = c;
}
public void setFloatingLocation(int x, int y)
{
floatFrame.setLocation(x, y);
floatFrame.invalidate();
floatFrame.validate();
floatFrame.repaint();
}
public void setOrientation(int orientation)
{
toolBar.setOrientation(orientation);
}
public void setRolloverBorders(boolean rollover)
{
if (rollover)
installRolloverBorders(toolBar);
else
installNonRolloverBorders(toolBar);
}
protected void uninstallComponents()
{
installNormalBorders(toolBar);
borders = null;
rolloverBorder = null;
nonRolloverBorder = null;
cachedBounds = null;
floatFrame = null;
dragWindow = null;
}
protected void uninstallDefaults()
{
toolBar.setBackground(null);
toolBar.setForeground(null);
toolBar.setFont(null);
dockingBorderColor = null;
dockingColor = null;
floatingBorderColor = null;
floatingColor = null;
}
protected void uninstallKeyboardActions()
{
}
protected void uninstallListeners()
{
toolBar.removeFocusListener(toolBarFocusListener);
toolBarFocusListener = null;
floatFrame.removeWindowListener(windowListener);
windowListener = null;
toolBar.removeContainerListener(toolBarContListener);
toolBarContListener = null;
toolBar.removeMouseMotionListener(dockingListener);
toolBar.removeMouseListener(dockingListener);
dockingListener = null;
}
public void uninstallUI(JComponent c)
{
uninstallKeyboardActions();
uninstallListeners();
uninstallComponents();
uninstallDefaults();
toolBar = null;
}
public class DockingListener implements MouseInputListener
{
protected boolean isDragging;
protected Point origin;
protected JToolBar toolBar;
public DockingListener(JToolBar t)
{
toolBar = t;
}
public void mouseClicked(MouseEvent e)
{
}
public void mouseDragged(MouseEvent e)
{
if (isDragging)
dragTo(e.getPoint(), origin);
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mouseMoved(MouseEvent e)
{
}
public void mousePressed(MouseEvent e)
{
if (! toolBar.isFloatable())
return;
Point ssd = e.getPoint();
Insets insets = toolBar.getInsets();
if (toolBar.getOrientation() == SwingConstants.HORIZONTAL)
{
if (e.getX() > insets.left)
return;
}
else
{
if (e.getY() > insets.top)
return;
}
origin = new Point(0, 0);
SwingUtilities.convertPointToScreen(ssd, toolBar);
if (! (SwingUtilities.getAncestorOfClass(Window.class, toolBar) instanceof UIResource))
origParent = toolBar.getParent();
SwingUtilities.convertPointToScreen(origin, toolBar);
isDragging = true;
if (dragWindow != null)
dragWindow.setOffset(new Point(e.getX(), e.getY()));
dragTo(e.getPoint(), origin);
}
public void mouseReleased(MouseEvent e)
{
if (! isDragging || ! toolBar.isFloatable())
return;
isDragging = false;
floatAt(e.getPoint(), origin);
dragWindow.hide();
}
}
protected class DragWindow extends Window
{
private Color borderColor;
private Point offset;
private DragWindow()
{
super(owner);
}
public Color getBorderColor()
{
if (borderColor == null)
return Color.BLACK;
return borderColor;
}
public Insets getInsets()
{
return new Insets(0, 0, 0, 0);
}
public Point getOffset()
{
return offset;
}
public void paint(Graphics g)
{
Color saved = g.getColor();
Rectangle b = getBounds();
g.setColor(getBorderColor());
g.drawRect(0, 0, b.width - 1, b.height - 1);
g.setColor(saved);
}
public void setBorderColor(Color c)
{
borderColor = c;
}
public void setOffset(Point p)
{
offset = p;
}
public void setOrientation(int o)
{
}
}
protected class FrameListener extends WindowAdapter
{
public void windowClosing(WindowEvent e)
{
Container parent = toolBar.getParent();
parent.remove(toolBar);
if (origParent != null)
{
origParent.add(toolBar,
(constraintBeforeFloating != null)
? constraintBeforeFloating : BorderLayout.NORTH);
toolBar.setOrientation(lastGoodOrientation);
}
origParent.invalidate();
origParent.validate();
origParent.repaint();
}
}
protected class PropertyListener implements PropertyChangeListener
{
public void propertyChange(PropertyChangeEvent e)
{
if (e.getPropertyName().equals("rollover"))
setRolloverBorders(toolBar.isRollover());
}
}
protected class ToolBarContListener implements ContainerListener
{
public void componentAdded(ContainerEvent e)
{
if (e.getChild() instanceof JButton)
{
JButton b = (JButton) e.getChild();
if (b.getBorder() != null)
borders.put(b, b.getBorder());
}
if (isRolloverBorders())
setBorderToRollover(e.getChild());
else
setBorderToNonRollover(e.getChild());
cachedBounds = toolBar.getPreferredSize();
cachedOrientation = toolBar.getOrientation();
}
public void componentRemoved(ContainerEvent e)
{
setBorderToNormal(e.getChild());
cachedBounds = toolBar.getPreferredSize();
cachedOrientation = toolBar.getOrientation();
}
}
private class ToolBarDialog extends JDialog implements UIResource
{
public ToolBarDialog()
{
super();
setName((toolBar.getName() != null) ? toolBar.getName() : "");
}
}
protected class ToolBarFocusListener implements FocusListener
{
protected ToolBarFocusListener()
{
}
public void focusGained(FocusEvent e)
{
}
public void focusLost(FocusEvent e)
{
}
}
private static class ToolBarBorder implements Border
{
private static final int offset = 10;
private static final int regular = 2;
public Insets getBorderInsets(Component c)
{
if (c instanceof JToolBar)
{
JToolBar tb = (JToolBar) c;
int orientation = tb.getOrientation();
if (! tb.isFloatable())
return new Insets(regular, regular, regular, regular);
else if (orientation == SwingConstants.HORIZONTAL)
return new Insets(regular, offset, regular, regular);
else
return new Insets(offset, regular, regular, regular);
}
return new Insets(0, 0, 0, 0);
}
public boolean isBorderOpaque()
{
return false;
}
private void paintBumps(Graphics g, int x, int y, int w, int h, int size,
Color c)
{
Color saved = g.getColor();
g.setColor(c);
int hgap = 2 * size;
int vgap = 4 * size;
int count = 0;
for (int i = x; i < (w + x); i += hgap)
for (int j = ((count++ % 2) == 0) ? y : (y + (2 * size)); j < (h + y);
j += vgap)
g.fillRect(i, j, size, size);
g.setColor(saved);
}
public void paintBorder(Component c, Graphics g, int x, int y, int width,
int height)
{
if (c instanceof JToolBar)
{
JToolBar tb = (JToolBar) c;
int orientation = tb.getOrientation();
if (orientation == SwingConstants.HORIZONTAL)
{
paintBumps(g, x, y, offset, height, 1, Color.WHITE);
paintBumps(g, x + 1, y + 1, offset - 1, height - 1, 1, Color.GRAY);
}
else
{
paintBumps(g, x, y, width, offset, 1, Color.WHITE);
paintBumps(g, x + 1, y + 1, width - 1, offset - 1, 1, Color.GRAY);
}
}
}
}
}