| /* BasicToolBarUI.java -- |
| Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc. |
| |
| This file is part of GNU Classpath. |
| |
| GNU Classpath is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License as published by |
| the Free Software Foundation; either version 2, or (at your option) |
| any later version. |
| |
| GNU Classpath is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with GNU Classpath; see the file COPYING. If not, write to the |
| Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
| 02110-1301 USA. |
| |
| Linking this library statically or dynamically with other modules is |
| making a combined work based on this library. Thus, the terms and |
| conditions of the GNU General Public License cover the whole |
| combination. |
| |
| As a special exception, the copyright holders of this library give you |
| permission to link this library with independent modules to produce an |
| executable, regardless of the license terms of these independent |
| modules, and to copy and distribute the resulting executable under |
| terms of your choice, provided that you also meet, for each linked |
| independent module, the terms and conditions of the license of that |
| module. An independent module is a module which is not derived from |
| or based on this library. If you modify this library, you may extend |
| this exception to your version of the library, but you are not |
| obligated to do so. If you do not wish to do so, delete this |
| exception statement from your version. */ |
| |
| |
| 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.ActionEvent; |
| 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.AbstractAction; |
| import javax.swing.AbstractButton; |
| import javax.swing.Action; |
| import javax.swing.ActionMap; |
| import javax.swing.InputMap; |
| import javax.swing.JButton; |
| import javax.swing.JComponent; |
| import javax.swing.JDialog; |
| import javax.swing.JFrame; |
| import javax.swing.JToolBar; |
| import javax.swing.KeyStroke; |
| import javax.swing.LookAndFeel; |
| import javax.swing.RootPaneContainer; |
| import javax.swing.SwingConstants; |
| import javax.swing.SwingUtilities; |
| import javax.swing.UIManager; |
| import javax.swing.border.Border; |
| import javax.swing.border.CompoundBorder; |
| import javax.swing.event.MouseInputListener; |
| import javax.swing.plaf.ActionMapUIResource; |
| import javax.swing.plaf.ComponentUI; |
| import javax.swing.plaf.ToolBarUI; |
| import javax.swing.plaf.UIResource; |
| import javax.swing.plaf.basic.BasicBorders.ButtonBorder; |
| |
| /** |
| * This is the Basic Look and Feel UI class for JToolBar. |
| */ |
| public class BasicToolBarUI extends ToolBarUI implements SwingConstants |
| { |
| |
| /** |
| * Implements the keyboard actions for JToolBar. |
| */ |
| static class ToolBarAction |
| extends AbstractAction |
| { |
| /** |
| * Performs the action. |
| */ |
| public void actionPerformed(ActionEvent event) |
| { |
| Object cmd = getValue("__command__"); |
| JToolBar toolBar = (JToolBar) event.getSource(); |
| BasicToolBarUI ui = (BasicToolBarUI) toolBar.getUI(); |
| |
| if (cmd.equals("navigateRight")) |
| ui.navigateFocusedComp(EAST); |
| else if (cmd.equals("navigateLeft")) |
| ui.navigateFocusedComp(WEST); |
| else if (cmd.equals("navigateUp")) |
| ui.navigateFocusedComp(NORTH); |
| else if (cmd.equals("navigateDown")) |
| ui.navigateFocusedComp(SOUTH); |
| else |
| assert false : "Shouldn't reach here"; |
| } |
| } |
| |
| /** Static owner of all DragWindows. |
| * This is package-private to avoid an accessor method. */ |
| static JFrame owner = new JFrame(); |
| |
| /** The border used when the JToolBar is in nonrollover mode. */ |
| private static Border nonRolloverBorder; |
| |
| /** The border used when the JToolBar is in rollover mode. */ |
| private static Border rolloverBorder; |
| |
| /** The last known BorderLayout constraint before floating. */ |
| protected String constraintBeforeFloating; |
| |
| /** The last known orientation of the JToolBar before floating. |
| * This is package-private to avoid an accessor method. */ |
| int lastGoodOrientation; |
| |
| /** The color of the border when it is dockable. */ |
| protected Color dockingBorderColor; |
| |
| /** The background color of the JToolBar when it is dockable. */ |
| protected Color dockingColor; |
| |
| /** The docking listener responsible for mouse events on the JToolBar. */ |
| protected MouseInputListener dockingListener; |
| |
| /** The window used for dragging the JToolBar. */ |
| protected BasicToolBarUI.DragWindow dragWindow; |
| |
| /** The color of the border when it is not dockable. */ |
| protected Color floatingBorderColor; |
| |
| /** The background color of the JToolBar when it is not dockable. */ |
| protected Color floatingColor; |
| |
| /** The index of the focused component. */ |
| protected int focusedCompIndex; |
| |
| /** The PropertyChangeListener for the JToolBar. */ |
| protected PropertyChangeListener propertyListener; |
| |
| /** The JToolBar this UI delegate is responsible for. */ |
| protected JToolBar toolBar; |
| |
| /** The Container listener for the JToolBar. */ |
| protected ContainerListener toolBarContListener; |
| |
| /** The Focus listener for the JToolBar. */ |
| protected FocusListener toolBarFocusListener; |
| |
| /** |
| * @deprecated since JDK1.3. |
| */ |
| protected KeyStroke leftKey; |
| |
| /** |
| * @deprecated since JDK1.3. |
| */ |
| protected KeyStroke rightKey; |
| |
| /** |
| * @deprecated since JDK1.3. |
| */ |
| protected KeyStroke upKey; |
| |
| /** |
| * @deprecated since JDK1.3. |
| */ |
| protected KeyStroke downKey; |
| |
| /** |
| * The floating window that is responsible for holding the JToolBar when it |
| * is dragged outside of its original parent. |
| */ |
| private transient Window floatFrame; |
| |
| /** The original parent of the JToolBar. |
| * This is package-private to avoid an accessor method. */ |
| transient Container origParent; |
| |
| /** A hashtable of components and their original borders. |
| * This is package-private to avoid an accessor method. */ |
| transient Hashtable borders; |
| |
| /** A window listener for the floatable frame. */ |
| private transient WindowListener windowListener; |
| |
| /** A set of cached bounds of the JToolBar. |
| * This is package-private to avoid an accessor method. */ |
| transient Dimension cachedBounds; |
| |
| /** The cached orientation of the JToolBar. |
| * This is package-private to avoid an accessor method. */ |
| transient int cachedOrientation; |
| |
| /** |
| * This method creates a new <code>BasicToolBarUI</code> object for the given JToolBar. |
| */ |
| public BasicToolBarUI() |
| { |
| // Do nothing here. |
| } |
| |
| /** |
| * This method returns whether the JToolBar can dock at the given position. |
| * |
| * @param c The component to try to dock in. |
| * @param p The position of the mouse cursor relative to the given |
| * component. |
| * |
| * @return Whether the JToolBar can dock. |
| */ |
| public boolean canDock(Component c, Point p) |
| { |
| return areaOfClick(c, p) != -1; |
| } |
| |
| /** |
| * This helper method returns the position of the JToolBar if it can dock. |
| * |
| * @param c The component to try to dock in. |
| * @param p The position of the mouse cursor relative to the given |
| * component. |
| * |
| * @return One of the SwingConstants directions or -1 if the JToolBar can't |
| * dock. |
| */ |
| private int areaOfClick(Component c, Point p) |
| { |
| // Has to dock in immediate parent, not eventual root container. |
| Rectangle pBounds = c.getBounds(); |
| |
| // XXX: In Sun's implementation, the space the toolbar has to dock is dependent on the size it had last. |
| Dimension d = toolBar.getSize(); |
| int limit = Math.min(d.width, d.height); |
| |
| // The order of checking is 1. top 2. bottom 3. left 4. right |
| 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; |
| } |
| |
| /** |
| * This method creates a new DockingListener for the JToolBar. |
| * |
| * @return A new DockingListener for the JToolBar. |
| */ |
| protected MouseInputListener createDockingListener() |
| { |
| return new DockingListener(toolBar); |
| } |
| |
| /** |
| * This method creates a new DragWindow for the given JToolBar. |
| * |
| * @param toolbar The JToolBar to create a DragWindow for. |
| * |
| * @return A new DragWindow. |
| */ |
| protected BasicToolBarUI.DragWindow createDragWindow(JToolBar toolbar) |
| { |
| return new DragWindow(); |
| } |
| |
| /** |
| * This method creates a new floating frame for the JToolBar. By default, |
| * this UI uses createFloatingWindow instead. This method of creating a |
| * floating frame is deprecated. |
| * |
| * @param toolbar The JToolBar to create a floating frame for. |
| * |
| * @return A new floating frame. |
| */ |
| protected JFrame createFloatingFrame(JToolBar toolbar) |
| { |
| // FIXME: Though deprecated, this should still work. |
| return null; |
| } |
| |
| /** |
| * This method creates a new floating window for the JToolBar. This is the |
| * method used by default to create a floating container for the JToolBar. |
| * |
| * @param toolbar The JToolBar to create a floating window for. |
| * |
| * @return A new floating window. |
| */ |
| protected RootPaneContainer createFloatingWindow(JToolBar toolbar) |
| { |
| // This one is used by default though. |
| return new ToolBarDialog(); |
| } |
| |
| /** |
| * This method creates a new WindowListener for the JToolBar. |
| * |
| * @return A new WindowListener. |
| */ |
| protected WindowListener createFrameListener() |
| { |
| return new FrameListener(); |
| } |
| |
| /** |
| * This method creates a new nonRolloverBorder for JButtons when the |
| * JToolBar's rollover property is set to false. |
| * |
| * @return A new NonRolloverBorder. |
| */ |
| protected Border createNonRolloverBorder() |
| { |
| Border b = UIManager.getBorder("ToolBar.nonrolloverBorder"); |
| |
| if (b == null) |
| { |
| b = new CompoundBorder( |
| new ButtonBorder(UIManager.getColor("Button.shadow"), |
| UIManager.getColor("Button.darkShadow"), |
| UIManager.getColor("Button.light"), |
| UIManager.getColor("Button.highlight")), |
| BasicBorders.getMarginBorder()); |
| } |
| |
| return b; } |
| |
| /** |
| * This method creates a new PropertyChangeListener for the JToolBar. |
| * |
| * @return A new PropertyChangeListener. |
| */ |
| protected PropertyChangeListener createPropertyListener() |
| { |
| return new PropertyListener(); |
| } |
| |
| /** |
| * This method creates a new rollover border for JButtons when the |
| * JToolBar's rollover property is set to true. |
| * |
| * @return A new rollover border. |
| */ |
| protected Border createRolloverBorder() |
| { |
| Border b = UIManager.getBorder("ToolBar.rolloverBorder"); |
| |
| if (b == null) |
| { |
| b = new CompoundBorder( |
| new ButtonBorder(UIManager.getColor("Button.shadow"), |
| UIManager.getColor("Button.darkShadow"), |
| UIManager.getColor("Button.light"), |
| UIManager.getColor("Button.highlight")), |
| BasicBorders.getMarginBorder()); |
| } |
| |
| return b; |
| } |
| |
| /** |
| * This method creates a new Container listener for the JToolBar. |
| * |
| * @return A new Container listener. |
| */ |
| protected ContainerListener createToolBarContListener() |
| { |
| return new ToolBarContListener(); |
| } |
| |
| /** |
| * This method creates a new FocusListener for the JToolBar. |
| * |
| * @return A new FocusListener for the JToolBar. |
| */ |
| protected FocusListener createToolBarFocusListener() |
| { |
| return new ToolBarFocusListener(); |
| } |
| |
| /** |
| * This method creates a new UI delegate for the given JComponent. |
| * |
| * @param c The JComponent to create a UI delegate for. |
| * |
| * @return A new UI delegate. |
| */ |
| public static ComponentUI createUI(JComponent c) |
| { |
| return new BasicToolBarUI(); |
| } |
| |
| /** |
| * This method is called to drag the DragWindow around when the JToolBar is |
| * being dragged around. |
| * |
| * @param position The mouse cursor coordinates relative to the JToolBar. |
| * @param origin The screen position of the JToolBar. |
| */ |
| 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); |
| |
| cachedOrientation = toolBar.getOrientation(); |
| cachedBounds = toolBar.getSize(); |
| 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(); |
| } |
| |
| /** |
| * This method is used at the end of a drag session to place the frame in |
| * either its original parent as a docked JToolBar or in its floating |
| * frame. |
| * |
| * @param position The position of the mouse cursor relative to the |
| * JToolBar. |
| * @param origin The screen position of the JToolBar before the drag session |
| * started. |
| */ |
| 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(); |
| } |
| |
| /** |
| * This method returns the docking color. |
| * |
| * @return The docking color. |
| */ |
| public Color getDockingColor() |
| { |
| return dockingColor; |
| } |
| |
| /** |
| * This method returns the Color which is displayed when over a floating |
| * area. |
| * |
| * @return The color which is displayed when over a floating area. |
| */ |
| public Color getFloatingColor() |
| { |
| return floatingColor; |
| } |
| |
| /** |
| * This method returns the maximum size of the given JComponent for this UI. |
| * |
| * @param c The JComponent to find the maximum size for. |
| * |
| * @return The maximum size for this UI. |
| */ |
| public Dimension getMaximumSize(JComponent c) |
| { |
| return getPreferredSize(c); |
| } |
| |
| /** |
| * This method returns the minimum size of the given JComponent for this UI. |
| * |
| * @param c The JComponent to find a minimum size for. |
| * |
| * @return The minimum size for this UI. |
| */ |
| public Dimension getMinimumSize(JComponent c) |
| { |
| return getPreferredSize(c); |
| } |
| |
| /** |
| * This method installs the needed components for the JToolBar. |
| */ |
| protected void installComponents() |
| { |
| floatFrame = (Window) createFloatingWindow(toolBar); |
| |
| dragWindow = createDragWindow(toolBar); |
| |
| nonRolloverBorder = createNonRolloverBorder(); |
| rolloverBorder = createRolloverBorder(); |
| |
| borders = new Hashtable(); |
| setRolloverBorders(toolBar.isRollover()); |
| |
| fillHashtable(); |
| } |
| |
| /** |
| * This method installs the defaults as specified by the look and feel. |
| */ |
| protected void installDefaults() |
| { |
| LookAndFeel.installBorder(toolBar, "ToolBar.border"); |
| LookAndFeel.installColorsAndFont(toolBar, "ToolBar.background", |
| "ToolBar.foreground", "ToolBar.font"); |
| |
| dockingBorderColor = UIManager.getColor("ToolBar.dockingForeground"); |
| dockingColor = UIManager.getColor("ToolBar.dockingBackground"); |
| |
| floatingBorderColor = UIManager.getColor("ToolBar.floatingForeground"); |
| floatingColor = UIManager.getColor("ToolBar.floatingBackground"); |
| } |
| |
| /** |
| * This method installs the keyboard actions for the JToolBar as specified |
| * by the look and feel. |
| */ |
| protected void installKeyboardActions() |
| { |
| // Install the input map. |
| InputMap inputMap = |
| (InputMap) SharedUIDefaults.get("ToolBar.ancestorInputMap"); |
| SwingUtilities.replaceUIInputMap(toolBar, |
| JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, |
| inputMap); |
| |
| // FIXME: The JDK uses a LazyActionMap for parentActionMap |
| SwingUtilities.replaceUIActionMap(toolBar, getActionMap()); |
| } |
| |
| /** |
| * Fetches the action map from the UI defaults, or create a new one |
| * if the action map hasn't been initialized. |
| * |
| * @return the action map |
| */ |
| private ActionMap getActionMap() |
| { |
| ActionMap am = (ActionMap) UIManager.get("ToolBar.actionMap"); |
| if (am == null) |
| { |
| am = createDefaultActions(); |
| UIManager.getLookAndFeelDefaults().put("ToolBar.actionMap", am); |
| } |
| return am; |
| } |
| |
| private ActionMap createDefaultActions() |
| { |
| ActionMapUIResource am = new ActionMapUIResource(); |
| Action action = new ToolBarAction(); |
| |
| am.put("navigateLeft", action); |
| am.put("navigateRight", action); |
| am.put("navigateUp", action); |
| am.put("navigateDown", action); |
| |
| return am; |
| } |
| |
| /** |
| * This method installs listeners for the JToolBar. |
| */ |
| protected void installListeners() |
| { |
| 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(); |
| if (toolBarFocusListener != null) |
| { |
| int count = toolBar.getComponentCount(); |
| for (int i = 0; i < count; i++) |
| toolBar.getComponent(i).addFocusListener(toolBarFocusListener); |
| } |
| } |
| |
| /** |
| * This method installs non rollover borders for each component inside the |
| * given JComponent. |
| * |
| * @param c The JComponent whose children need to have non rollover borders |
| * installed. |
| */ |
| protected void installNonRolloverBorders(JComponent c) |
| { |
| Component[] components = toolBar.getComponents(); |
| |
| for (int i = 0; i < components.length; i++) |
| setBorderToNonRollover(components[i]); |
| } |
| |
| /** |
| * This method installs normal (or their original) borders for each |
| * component inside the given JComponent. |
| * |
| * @param c The JComponent whose children need to have their original |
| * borders installed. |
| */ |
| protected void installNormalBorders(JComponent c) |
| { |
| Component[] components = toolBar.getComponents(); |
| |
| for (int i = 0; i < components.length; i++) |
| setBorderToNormal(components[i]); |
| } |
| |
| /** |
| * This method install rollover borders for each component inside the given |
| * JComponent. |
| * |
| * @param c The JComponent whose children need to have rollover borders |
| * installed. |
| */ |
| protected void installRolloverBorders(JComponent c) |
| { |
| Component[] components = toolBar.getComponents(); |
| |
| for (int i = 0; i < components.length; i++) |
| setBorderToRollover(components[i]); |
| } |
| |
| /** |
| * This method fills the borders hashtable with a list of components that |
| * are JButtons and their borders. |
| */ |
| private void fillHashtable() |
| { |
| Component[] c = toolBar.getComponents(); |
| |
| for (int i = 0; i < c.length; i++) |
| { |
| if (c[i] instanceof JButton) |
| { |
| // Don't really care about anything other than JButtons |
| JButton b = (JButton) c[i]; |
| |
| if (b.getBorder() != null) |
| borders.put(b, b.getBorder()); |
| } |
| } |
| } |
| |
| /** |
| * This method installs the UI for the given JComponent. |
| * |
| * @param c The JComponent to install a UI for. |
| */ |
| public void installUI(JComponent c) |
| { |
| super.installUI(c); |
| |
| if (c instanceof JToolBar) |
| { |
| toolBar = (JToolBar) c; |
| installDefaults(); |
| installComponents(); |
| installListeners(); |
| installKeyboardActions(); |
| } |
| } |
| |
| /** |
| * This method returns whether the JToolBar is floating. |
| * |
| * @return Whether the JToolBar is floating. |
| */ |
| public boolean isFloating() |
| { |
| return floatFrame.isVisible(); |
| } |
| |
| /** |
| * This method returns whether rollover borders have been set. |
| * |
| * @return Whether rollover borders have been set. |
| */ |
| public boolean isRolloverBorders() |
| { |
| return toolBar.isRollover(); |
| } |
| |
| /** |
| * This method navigates in the given direction giving focus to the next |
| * component in the given direction. |
| * |
| * @param direction The direction to give focus to. |
| */ |
| protected void navigateFocusedComp(int direction) |
| { |
| int count = toolBar.getComponentCount(); |
| switch (direction) |
| { |
| case EAST: |
| case SOUTH: |
| if (focusedCompIndex >= 0 && focusedCompIndex < count) |
| { |
| int i = focusedCompIndex + 1; |
| boolean focusRequested = false; |
| // Find component to focus and request focus on it. |
| while (i != focusedCompIndex && ! focusRequested) |
| { |
| if (i >= count) |
| i = 0; |
| Component comp = toolBar.getComponentAtIndex(i++); |
| if (comp != null && comp.isFocusable() |
| && comp.isEnabled()) |
| { |
| comp.requestFocus(); |
| focusRequested = true; |
| } |
| } |
| } |
| break; |
| case WEST: |
| case NORTH: |
| if (focusedCompIndex >= 0 && focusedCompIndex < count) |
| { |
| int i = focusedCompIndex - 1; |
| boolean focusRequested = false; |
| // Find component to focus and request focus on it. |
| while (i != focusedCompIndex && ! focusRequested) |
| { |
| if (i < 0) |
| i = count - 1; |
| Component comp = toolBar.getComponentAtIndex(i--); |
| if (comp != null && comp.isFocusable() |
| && comp.isEnabled()) |
| { |
| comp.requestFocus(); |
| focusRequested = true; |
| } |
| } |
| } |
| break; |
| default: |
| break; |
| } |
| } |
| |
| /** |
| * This method sets the border of the given component to a non rollover |
| * border. |
| * |
| * @param c The Component whose border needs to be set. |
| */ |
| protected void setBorderToNonRollover(Component c) |
| { |
| if (c instanceof AbstractButton) |
| { |
| AbstractButton b = (AbstractButton) c; |
| b.setRolloverEnabled(false); |
| |
| // Save old border in hashtable. |
| borders.put(b, b.getBorder()); |
| |
| b.setBorder(nonRolloverBorder); |
| } |
| } |
| |
| /** |
| * This method sets the border of the given component to its original value. |
| * |
| * @param c The Component whose border needs to be set. |
| */ |
| protected void setBorderToNormal(Component c) |
| { |
| if (c instanceof AbstractButton) |
| { |
| AbstractButton b = (AbstractButton) c; |
| b.setRolloverEnabled(true); |
| b.setBorder((Border) borders.remove(b)); |
| } |
| } |
| |
| /** |
| * This method sets the border of the given component to a rollover border. |
| * |
| * @param c The Component whose border needs to be set. |
| */ |
| protected void setBorderToRollover(Component c) |
| { |
| if (c instanceof AbstractButton) |
| { |
| AbstractButton b = (AbstractButton) c; |
| b.setRolloverEnabled(false); |
| |
| // Save old border in hashtable. |
| borders.put(b, b.getBorder()); |
| |
| b.setBorder(rolloverBorder); |
| } |
| } |
| |
| /** |
| * This method sets the docking color. |
| * |
| * @param c The docking color. |
| */ |
| public void setDockingColor(Color c) |
| { |
| dockingColor = c; |
| } |
| |
| /** |
| * This method sets the floating property for the JToolBar. |
| * |
| * @param b Whether the JToolBar is floating. |
| * @param p FIXME |
| */ |
| public void setFloating(boolean b, Point p) |
| { |
| // FIXME: use p for something. It's not location |
| // since we already have setFloatingLocation. |
| floatFrame.setVisible(b); |
| } |
| |
| /** |
| * This method sets the color displayed when the JToolBar is not in a |
| * dockable area. |
| * |
| * @param c The floating color. |
| */ |
| public void setFloatingColor(Color c) |
| { |
| floatingColor = c; |
| } |
| |
| /** |
| * This method sets the floating location of the JToolBar. |
| * |
| * @param x The x coordinate for the floating frame. |
| * @param y The y coordinate for the floating frame. |
| */ |
| public void setFloatingLocation(int x, int y) |
| { |
| // x,y are the coordinates of the new JFrame created to store the toolbar |
| // XXX: The floating location is bogus is not floating. |
| floatFrame.setLocation(x, y); |
| floatFrame.invalidate(); |
| floatFrame.validate(); |
| floatFrame.repaint(); |
| } |
| |
| /** |
| * This is a convenience method for changing the orientation of the |
| * JToolBar. |
| * |
| * @param orientation The new orientation. |
| */ |
| public void setOrientation(int orientation) |
| { |
| toolBar.setOrientation(orientation); |
| } |
| |
| /** |
| * This method changes the child components to have rollover borders if the |
| * given parameter is true. Otherwise, the components are set to have non |
| * rollover borders. |
| * |
| * @param rollover Whether the children will have rollover borders. |
| */ |
| public void setRolloverBorders(boolean rollover) |
| { |
| if (rollover) |
| installRolloverBorders(toolBar); |
| else |
| installNonRolloverBorders(toolBar); |
| } |
| |
| /** |
| * This method uninstall UI installed components from the JToolBar. |
| */ |
| protected void uninstallComponents() |
| { |
| installNormalBorders(toolBar); |
| borders = null; |
| cachedBounds = null; |
| |
| floatFrame = null; |
| dragWindow = null; |
| } |
| |
| /** |
| * This method removes the defaults installed by the Look and Feel. |
| */ |
| protected void uninstallDefaults() |
| { |
| toolBar.setBackground(null); |
| toolBar.setForeground(null); |
| toolBar.setFont(null); |
| |
| dockingBorderColor = null; |
| dockingColor = null; |
| floatingBorderColor = null; |
| floatingColor = null; |
| } |
| |
| /** |
| * This method uninstalls keyboard actions installed by the UI. |
| */ |
| protected void uninstallKeyboardActions() |
| { |
| SwingUtilities.replaceUIInputMap(toolBar, JComponent. |
| WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null); |
| SwingUtilities.replaceUIActionMap(toolBar, null); |
| } |
| |
| /** |
| * This method uninstalls listeners installed by the UI. |
| */ |
| protected void uninstallListeners() |
| { |
| if (toolBarFocusListener != null) |
| { |
| int count = toolBar.getComponentCount(); |
| for (int i = 0; i < count; i++) |
| toolBar.getComponent(i).removeFocusListener(toolBarFocusListener); |
| toolBarFocusListener = null; |
| } |
| |
| floatFrame.removeWindowListener(windowListener); |
| windowListener = null; |
| |
| toolBar.removeContainerListener(toolBarContListener); |
| toolBarContListener = null; |
| |
| toolBar.removeMouseMotionListener(dockingListener); |
| toolBar.removeMouseListener(dockingListener); |
| dockingListener = null; |
| } |
| |
| /** |
| * This method uninstalls the UI. |
| * |
| * @param c The JComponent that is having this UI removed. |
| */ |
| public void uninstallUI(JComponent c) |
| { |
| uninstallKeyboardActions(); |
| uninstallListeners(); |
| uninstallComponents(); |
| uninstallDefaults(); |
| toolBar = null; |
| } |
| |
| /** |
| * This is the MouseHandler class that allows the user to drag the JToolBar |
| * in and out of the parent and dock it if it can. |
| */ |
| public class DockingListener implements MouseInputListener |
| { |
| /** Whether the JToolBar is being dragged. */ |
| protected boolean isDragging; |
| |
| /** |
| * The origin point. This point is saved from the beginning press and is |
| * used until the end of the drag session. |
| */ |
| protected Point origin; |
| |
| /** The JToolBar being dragged. */ |
| protected JToolBar toolBar; |
| |
| /** |
| * Creates a new DockingListener object. |
| * |
| * @param t The JToolBar this DockingListener is being used for. |
| */ |
| public DockingListener(JToolBar t) |
| { |
| toolBar = t; |
| } |
| |
| /** |
| * This method is called when the mouse is clicked. |
| * |
| * @param e The MouseEvent. |
| */ |
| public void mouseClicked(MouseEvent e) |
| { |
| // Nothing to do here. |
| } |
| |
| /** |
| * This method is called when the mouse is dragged. It delegates the drag |
| * painting to the dragTo method. |
| * |
| * @param e The MouseEvent. |
| */ |
| public void mouseDragged(MouseEvent e) |
| { |
| if (isDragging) |
| dragTo(e.getPoint(), origin); |
| } |
| |
| /** |
| * This method is called when the mouse enters the JToolBar. |
| * |
| * @param e The MouseEvent. |
| */ |
| public void mouseEntered(MouseEvent e) |
| { |
| // Nothing to do here. |
| } |
| |
| /** |
| * This method is called when the mouse exits the JToolBar. |
| * |
| * @param e The MouseEvent. |
| */ |
| public void mouseExited(MouseEvent e) |
| { |
| // Nothing to do here. |
| } |
| |
| /** |
| * This method is called when the mouse is moved in the JToolBar. |
| * |
| * @param e The MouseEvent. |
| */ |
| public void mouseMoved(MouseEvent e) |
| { |
| // Nothing to do here. |
| } |
| |
| /** |
| * This method is called when the mouse is pressed in the JToolBar. If the |
| * press doesn't occur in a place where it causes the JToolBar to be |
| * dragged, it returns. Otherwise, it starts a drag session. |
| * |
| * @param e The MouseEvent. |
| */ |
| public void mousePressed(MouseEvent e) |
| { |
| if (! toolBar.isFloatable()) |
| return; |
| |
| Point ssd = e.getPoint(); |
| Insets insets = toolBar.getInsets(); |
| |
| // Verify that this click occurs in the top inset. |
| if (toolBar.getOrientation() == SwingConstants.HORIZONTAL) |
| { |
| if (e.getX() > insets.left) |
| return; |
| } |
| else |
| { |
| if (e.getY() > insets.top) |
| return; |
| } |
| |
| origin = new Point(0, 0); |
| if (toolBar.isShowing()) |
| SwingUtilities.convertPointToScreen(ssd, toolBar); |
| |
| if (! (SwingUtilities.getAncestorOfClass(Window.class, toolBar) instanceof UIResource)) |
| // Need to know who keeps the toolBar if it gets dragged back into it. |
| origParent = toolBar.getParent(); |
| |
| if (toolBar.isShowing()) |
| SwingUtilities.convertPointToScreen(origin, toolBar); |
| |
| isDragging = true; |
| |
| if (dragWindow != null) |
| dragWindow.setOffset(new Point(cachedBounds.width / 2, |
| cachedBounds.height / 2)); |
| |
| dragTo(e.getPoint(), origin); |
| } |
| |
| /** |
| * This method is called when the mouse is released from the JToolBar. |
| * |
| * @param e The MouseEvent. |
| */ |
| public void mouseReleased(MouseEvent e) |
| { |
| if (! isDragging || ! toolBar.isFloatable()) |
| return; |
| |
| isDragging = false; |
| floatAt(e.getPoint(), origin); |
| dragWindow.hide(); |
| } |
| } |
| |
| /** |
| * This is the window that appears when the JToolBar is being dragged |
| * around. |
| */ |
| protected class DragWindow extends Window |
| { |
| /** |
| * The current border color. It changes depending on whether the JToolBar |
| * is over a place that allows it to dock. |
| */ |
| private Color borderColor; |
| |
| /** The between the mouse and the top left corner of the window. */ |
| private Point offset; |
| |
| /** |
| * Creates a new DragWindow object. |
| * This is package-private to avoid an accessor method. |
| */ |
| DragWindow() |
| { |
| super(owner); |
| } |
| |
| /** |
| * The color that the border should be. |
| * |
| * @return The border color. |
| */ |
| public Color getBorderColor() |
| { |
| if (borderColor == null) |
| return Color.BLACK; |
| |
| return borderColor; |
| } |
| |
| /** |
| * This method returns the insets for the DragWindow. |
| * |
| * @return The insets for the DragWindow. |
| */ |
| public Insets getInsets() |
| { |
| // This window has no decorations, so insets are empty. |
| return new Insets(0, 0, 0, 0); |
| } |
| |
| /** |
| * This method returns the mouse offset from the top left corner of the |
| * DragWindow. |
| * |
| * @return The mouse offset. |
| */ |
| public Point getOffset() |
| { |
| return offset; |
| } |
| |
| /** |
| * This method paints the DragWindow. |
| * |
| * @param g The Graphics object to paint with. |
| */ |
| public void paint(Graphics g) |
| { |
| // No visiting children necessary. |
| Color saved = g.getColor(); |
| Rectangle b = getBounds(); |
| |
| g.setColor(getBorderColor()); |
| g.drawRect(0, 0, b.width - 1, b.height - 1); |
| |
| g.setColor(saved); |
| } |
| |
| /** |
| * This method changes the border color. |
| * |
| * @param c The new border color. |
| */ |
| public void setBorderColor(Color c) |
| { |
| borderColor = c; |
| } |
| |
| /** |
| * This method changes the mouse offset. |
| * |
| * @param p The new mouse offset. |
| */ |
| public void setOffset(Point p) |
| { |
| offset = p; |
| } |
| |
| /** |
| * Sets the orientation of the toolbar and the |
| * drag window. |
| * |
| * @param o - the new orientation of the toolbar and drag |
| * window. |
| */ |
| public void setOrientation(int o) |
| { |
| toolBar.setOrientation(o); |
| if (dragWindow != null) |
| dragWindow.setOrientation(o); |
| } |
| } |
| |
| /** |
| * This helper class listens for Window events from the floatable window and |
| * if it is closed, returns the JToolBar to the last known good location. |
| */ |
| protected class FrameListener extends WindowAdapter |
| { |
| /** |
| * This method is called when the floating window is closed. |
| * |
| * @param e The WindowEvent. |
| */ |
| 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(); |
| } |
| } |
| |
| /** |
| * This helper class listens for PropertyChangeEvents from the JToolBar. |
| */ |
| protected class PropertyListener implements PropertyChangeListener |
| { |
| /** |
| * This method is called when a property from the JToolBar is changed. |
| * |
| * @param e The PropertyChangeEvent. |
| */ |
| public void propertyChange(PropertyChangeEvent e) |
| { |
| // FIXME: need name properties so can change floatFrame title. |
| if (e.getPropertyName().equals("rollover") && toolBar != null) |
| setRolloverBorders(toolBar.isRollover()); |
| } |
| } |
| |
| /** |
| * This helper class listens for components added to and removed from the |
| * JToolBar. |
| */ |
| protected class ToolBarContListener implements ContainerListener |
| { |
| /** |
| * This method is responsible for setting rollover or non rollover for new |
| * buttons added to the JToolBar. |
| * |
| * @param e The ContainerEvent. |
| */ |
| 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(); |
| |
| Component c = e.getChild(); |
| if (toolBarFocusListener != null) |
| c.addFocusListener(toolBarFocusListener); |
| } |
| |
| /** |
| * This method is responsible for giving the child components their |
| * original borders when they are removed. |
| * |
| * @param e The ContainerEvent. |
| */ |
| public void componentRemoved(ContainerEvent e) |
| { |
| setBorderToNormal(e.getChild()); |
| cachedBounds = toolBar.getPreferredSize(); |
| cachedOrientation = toolBar.getOrientation(); |
| |
| Component c = e.getChild(); |
| if (toolBarFocusListener != null) |
| c.removeFocusListener(toolBarFocusListener); |
| } |
| } |
| |
| /** |
| * This is the floating window that is returned when getFloatingWindow is |
| * called. |
| */ |
| private class ToolBarDialog extends JDialog implements UIResource |
| { |
| /** |
| * Creates a new ToolBarDialog object with the name given by the JToolBar. |
| */ |
| public ToolBarDialog() |
| { |
| super(); |
| setName((toolBar.getName() != null) ? toolBar.getName() : ""); |
| } |
| } |
| |
| /** |
| * DOCUMENT ME! |
| */ |
| protected class ToolBarFocusListener implements FocusListener |
| { |
| /** |
| * Creates a new ToolBarFocusListener object. |
| */ |
| protected ToolBarFocusListener() |
| { |
| // Nothing to do here. |
| } |
| |
| /** |
| * Receives notification when the toolbar or one of it's component |
| * receives the keyboard input focus. |
| * |
| * @param e the focus event |
| */ |
| public void focusGained(FocusEvent e) |
| { |
| Component c = e.getComponent(); |
| focusedCompIndex = toolBar.getComponentIndex(c); |
| } |
| |
| /** |
| * Receives notification when the toolbar or one of it's component |
| * looses the keyboard input focus. |
| * |
| * @param e the focus event |
| */ |
| public void focusLost(FocusEvent e) |
| { |
| // Do nothing here. |
| } |
| } |
| |
| /** |
| * This helper class acts as the border for the JToolBar. |
| */ |
| private static class ToolBarBorder implements Border |
| { |
| /** The size of the larger, draggable side of the border. */ |
| private static final int offset = 10; |
| |
| /** The other sides. */ |
| private static final int regular = 2; |
| |
| /** |
| * This method returns the border insets for the JToolBar. |
| * |
| * @param c The Component to find insets for. |
| * |
| * @return The border insets. |
| */ |
| 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); |
| } |
| |
| /** |
| * This method returns whether the border is opaque. |
| * |
| * @return Whether the border is opaque. |
| */ |
| public boolean isBorderOpaque() |
| { |
| return false; |
| } |
| |
| /** |
| * This method paints the ribbed area of the border. |
| * |
| * @param g The Graphics object to paint with. |
| * @param x The x coordinate of the area. |
| * @param y The y coordinate of the area. |
| * @param w The width of the area. |
| * @param h The height of the area. |
| * @param size The size of the bump. |
| * @param c The color of the bumps. |
| */ |
| 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); |
| } |
| |
| /** |
| * This method paints the border around the given Component. |
| * |
| * @param c The Component whose border is being painted. |
| * @param g The Graphics object to paint with. |
| * @param x The x coordinate of the component. |
| * @param y The y coordinate of the component. |
| * @param width The width of the component. |
| * @param height The height of the component. |
| */ |
| 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); |
| } |
| } |
| } |
| } |
| } |