All Downloads are FREE. Search and download functionalities are using the official Maven repository.

META-INF.modules.java.desktop.classes.javax.swing.plaf.basic.BasicToolBarUI Maven / Gradle / Ivy

/*
 * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package javax.swing.plaf.basic;

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

import java.beans.*;

import java.util.Hashtable;
import java.util.HashMap;

import javax.swing.border.*;
import javax.swing.plaf.*;
import sun.swing.DefaultLookup;
import sun.swing.UIAction;


/**
 * A Basic L&F implementation of ToolBarUI.  This implementation
 * is a "combined" view/controller.
 *
 * @author Georges Saab
 * @author Jeff Shapiro
 */
public class BasicToolBarUI extends ToolBarUI implements SwingConstants
{
    /**
     * The instance of {@code JToolBar}.
     */
    protected JToolBar toolBar;
    private boolean floating;
    private int floatingX;
    private int floatingY;
    private JFrame floatingFrame;
    private RootPaneContainer floatingToolBar;
    /**
     * The instance of {@code DragWindow}.
     */
    protected DragWindow dragWindow;
    private Container dockingSource;
    private int dockingSensitivity = 0;
    /**
     * The index of the focused component.
     */
    protected int focusedCompIndex = -1;

    /**
     * The background color of the docking border.
     */
    protected Color dockingColor = null;
    /**
     * The background color of the not docking border.
     */
    protected Color floatingColor = null;
    /**
     * The color of the docking border.
     */
    protected Color dockingBorderColor = null;
    /**
     * The color of the not docking border.
     */
    protected Color floatingBorderColor = null;

    /**
     * The instance of a {@code MouseInputListener}.
     */
    protected MouseInputListener dockingListener;
    /**
     * The instance of a {@code PropertyChangeListener}.
     */
    protected PropertyChangeListener propertyListener;

    /**
     * The instance of a {@code ContainerListener}.
     */
    protected ContainerListener toolBarContListener;
    /**
     * The instance of a {@code FocusListener}.
     */
    protected FocusListener toolBarFocusListener;
    private Handler handler;

    /**
     * The layout before floating.
     */
    protected String constraintBeforeFloating = BorderLayout.NORTH;

    // Rollover button implementation.
    private static String IS_ROLLOVER = "JToolBar.isRollover";
    private static Border rolloverBorder;
    private static Border nonRolloverBorder;
    private static Border nonRolloverToggleBorder;
    private boolean rolloverBorders = false;

    private HashMap borderTable = new HashMap();
    private Hashtable rolloverTable = new Hashtable();


    /**
     * As of Java 2 platform v1.3 this previously undocumented field is no
     * longer used.
     * Key bindings are now defined by the LookAndFeel, please refer to
     * the key bindings specification for further details.
     *
     * @deprecated As of Java 2 platform v1.3.
     */
    @Deprecated
    protected KeyStroke upKey;
    /**
     * As of Java 2 platform v1.3 this previously undocumented field is no
     * longer used.
     * Key bindings are now defined by the LookAndFeel, please refer to
     * the key bindings specification for further details.
     *
     * @deprecated As of Java 2 platform v1.3.
     */
    @Deprecated
    protected KeyStroke downKey;
    /**
     * As of Java 2 platform v1.3 this previously undocumented field is no
     * longer used.
     * Key bindings are now defined by the LookAndFeel, please refer to
     * the key bindings specification for further details.
     *
     * @deprecated As of Java 2 platform v1.3.
     */
    @Deprecated
    protected KeyStroke leftKey;
    /**
     * As of Java 2 platform v1.3 this previously undocumented field is no
     * longer used.
     * Key bindings are now defined by the LookAndFeel, please refer to
     * the key bindings specification for further details.
     *
     * @deprecated As of Java 2 platform v1.3.
     */
    @Deprecated
    protected KeyStroke rightKey;


    private static String FOCUSED_COMP_INDEX = "JToolBar.focusedCompIndex";

    /**
     * Constructs a new instance of {@code BasicToolBarUI}.
     *
     * @param c a component
     * @return a new instance of {@code BasicToolBarUI}
     */
    public static ComponentUI createUI( JComponent c )
    {
        return new BasicToolBarUI();
    }

    public void installUI( JComponent c )
    {
        toolBar = (JToolBar) c;

        // Set defaults
        installDefaults();
        installComponents();
        installListeners();
        installKeyboardActions();

        // Initialize instance vars
        dockingSensitivity = 0;
        floating = false;
        floatingX = floatingY = 0;
        floatingToolBar = null;

        setOrientation( toolBar.getOrientation() );
        LookAndFeel.installProperty(c, "opaque", Boolean.TRUE);

        if ( c.getClientProperty( FOCUSED_COMP_INDEX ) != null )
        {
            focusedCompIndex = ( (Integer) ( c.getClientProperty( FOCUSED_COMP_INDEX ) ) ).intValue();
        }
    }

    public void uninstallUI( JComponent c )
    {

        // Clear defaults
        uninstallDefaults();
        uninstallComponents();
        uninstallListeners();
        uninstallKeyboardActions();

        // Clear instance vars
        if (isFloating())
            setFloating(false, null);

        floatingToolBar = null;
        dragWindow = null;
        dockingSource = null;

        c.putClientProperty( FOCUSED_COMP_INDEX, Integer.valueOf( focusedCompIndex ) );
    }

    /**
     * Installs default properties.
     */
    protected void installDefaults( )
    {
        LookAndFeel.installBorder(toolBar,"ToolBar.border");
        LookAndFeel.installColorsAndFont(toolBar,
                                              "ToolBar.background",
                                              "ToolBar.foreground",
                                              "ToolBar.font");
        // Toolbar specific defaults
        if ( dockingColor == null || dockingColor instanceof UIResource )
            dockingColor = UIManager.getColor("ToolBar.dockingBackground");
        if ( floatingColor == null || floatingColor instanceof UIResource )
            floatingColor = UIManager.getColor("ToolBar.floatingBackground");
        if ( dockingBorderColor == null ||
             dockingBorderColor instanceof UIResource )
            dockingBorderColor = UIManager.getColor("ToolBar.dockingForeground");
        if ( floatingBorderColor == null ||
             floatingBorderColor instanceof UIResource )
            floatingBorderColor = UIManager.getColor("ToolBar.floatingForeground");

        // ToolBar rollover button borders
        Object rolloverProp = toolBar.getClientProperty( IS_ROLLOVER );
        if (rolloverProp == null) {
            rolloverProp = UIManager.get("ToolBar.isRollover");
        }
        if ( rolloverProp != null ) {
            rolloverBorders = ((Boolean)rolloverProp).booleanValue();
        }

        if (rolloverBorder == null) {
            rolloverBorder = createRolloverBorder();
        }
        if (nonRolloverBorder == null) {
            nonRolloverBorder = createNonRolloverBorder();
        }
        if (nonRolloverToggleBorder == null) {
            nonRolloverToggleBorder = createNonRolloverToggleBorder();
        }


        setRolloverBorders( isRolloverBorders() );
    }

    /**
     * Uninstalls default properties.
     */
    protected void uninstallDefaults( )
    {
        LookAndFeel.uninstallBorder(toolBar);
        dockingColor = null;
        floatingColor = null;
        dockingBorderColor = null;
        floatingBorderColor = null;

        installNormalBorders(toolBar);

        rolloverBorder = null;
        nonRolloverBorder = null;
        nonRolloverToggleBorder = null;
    }

    /**
     * Registers components.
     */
    protected void installComponents( )
    {
    }

    /**
     * Unregisters components.
     */
    protected void uninstallComponents( )
    {
    }

    /**
     * Registers listeners.
     */
    protected void installListeners( )
    {
        dockingListener = createDockingListener( );

        if ( dockingListener != null )
        {
            toolBar.addMouseMotionListener( dockingListener );
            toolBar.addMouseListener( dockingListener );
        }

        propertyListener = createPropertyListener();  // added in setFloating
        if (propertyListener != null) {
            toolBar.addPropertyChangeListener(propertyListener);
        }

        toolBarContListener = createToolBarContListener();
        if ( toolBarContListener != null ) {
            toolBar.addContainerListener( toolBarContListener );
        }

        toolBarFocusListener = createToolBarFocusListener();

        if ( toolBarFocusListener != null )
        {
            // Put focus listener on all components in toolbar
            Component[] components = toolBar.getComponents();

            for (Component component : components) {
                component.addFocusListener(toolBarFocusListener);
            }
        }
    }

    /**
     * Unregisters listeners.
     */
    protected void uninstallListeners( )
    {
        if ( dockingListener != null )
        {
            toolBar.removeMouseMotionListener(dockingListener);
            toolBar.removeMouseListener(dockingListener);

            dockingListener = null;
        }

        if ( propertyListener != null )
        {
            toolBar.removePropertyChangeListener(propertyListener);
            propertyListener = null;  // removed in setFloating
        }

        if ( toolBarContListener != null )
        {
            toolBar.removeContainerListener( toolBarContListener );
            toolBarContListener = null;
        }

        if ( toolBarFocusListener != null )
        {
            // Remove focus listener from all components in toolbar
            Component[] components = toolBar.getComponents();

            for (Component component : components) {
                component.removeFocusListener(toolBarFocusListener);
            }

            toolBarFocusListener = null;
        }
        handler = null;
    }

    /**
     * Registers keyboard actions.
     */
    protected void installKeyboardActions( )
    {
        InputMap km = getInputMap(JComponent.
                                  WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);

        SwingUtilities.replaceUIInputMap(toolBar, JComponent.
                                         WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
                                         km);

    LazyActionMap.installLazyActionMap(toolBar, BasicToolBarUI.class,
            "ToolBar.actionMap");
    }

    InputMap getInputMap(int condition) {
        if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
            return (InputMap)DefaultLookup.get(toolBar, this,
                    "ToolBar.ancestorInputMap");
        }
        return null;
    }

    static void loadActionMap(LazyActionMap map) {
        map.put(new Actions(Actions.NAVIGATE_RIGHT));
        map.put(new Actions(Actions.NAVIGATE_LEFT));
        map.put(new Actions(Actions.NAVIGATE_UP));
        map.put(new Actions(Actions.NAVIGATE_DOWN));
    }

    /**
     * Unregisters keyboard actions.
     */
    protected void uninstallKeyboardActions( )
    {
        SwingUtilities.replaceUIActionMap(toolBar, null);
        SwingUtilities.replaceUIInputMap(toolBar, JComponent.
                                         WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
                                         null);
    }

    /**
     * Navigates the focused component.
     *
     * @param direction a direction
     */
    @SuppressWarnings("deprecation")
    protected void navigateFocusedComp(int direction)
    {
        int nComp = toolBar.getComponentCount();
        int j;

        switch ( direction )
        {
            case EAST:
            case SOUTH:

                if ( focusedCompIndex < 0 || focusedCompIndex >= nComp ) break;

                j = focusedCompIndex + 1;

                while ( j != focusedCompIndex )
                {
                    if ( j >= nComp ) j = 0;
                    Component comp = toolBar.getComponentAtIndex( j++ );

                    if ( comp != null && comp.isFocusTraversable() && comp.isEnabled() )
                    {
                        comp.requestFocus();
                        break;
                    }
                }

                break;

            case WEST:
            case NORTH:

                if ( focusedCompIndex < 0 || focusedCompIndex >= nComp ) break;

                j = focusedCompIndex - 1;

                while ( j != focusedCompIndex )
                {
                    if ( j < 0 ) j = nComp - 1;
                    Component comp = toolBar.getComponentAtIndex( j-- );

                    if ( comp != null && comp.isFocusTraversable() && comp.isEnabled() )
                    {
                        comp.requestFocus();
                        break;
                    }
                }

                break;

            default:
                break;
        }
    }

    /**
     * Creates a rollover border for toolbar components. The
     * rollover border will be installed if rollover borders are
     * enabled.
     * 

* Override this method to provide an alternate rollover border. * * @return a rollover border for toolbar components * @since 1.4 */ protected Border createRolloverBorder() { Object border = UIManager.get("ToolBar.rolloverBorder"); if (border != null) { return (Border)border; } UIDefaults table = UIManager.getLookAndFeelDefaults(); return new CompoundBorder(new BasicBorders.RolloverButtonBorder( table.getColor("controlShadow"), table.getColor("controlDkShadow"), table.getColor("controlHighlight"), table.getColor("controlLtHighlight")), new BasicBorders.RolloverMarginBorder()); } /** * Creates the non rollover border for toolbar components. This * border will be installed as the border for components added * to the toolbar if rollover borders are not enabled. *

* Override this method to provide an alternate rollover border. * * @return the non rollover border for toolbar components * @since 1.4 */ protected Border createNonRolloverBorder() { Object border = UIManager.get("ToolBar.nonrolloverBorder"); if (border != null) { return (Border)border; } UIDefaults table = UIManager.getLookAndFeelDefaults(); return new CompoundBorder(new BasicBorders.ButtonBorder( table.getColor("Button.shadow"), table.getColor("Button.darkShadow"), table.getColor("Button.light"), table.getColor("Button.highlight")), new BasicBorders.RolloverMarginBorder()); } /** * Creates a non rollover border for Toggle buttons in the toolbar. */ private Border createNonRolloverToggleBorder() { UIDefaults table = UIManager.getLookAndFeelDefaults(); return new CompoundBorder(new BasicBorders.RadioButtonBorder( table.getColor("ToggleButton.shadow"), table.getColor("ToggleButton.darkShadow"), table.getColor("ToggleButton.light"), table.getColor("ToggleButton.highlight")), new BasicBorders.RolloverMarginBorder()); } /** * No longer used, use BasicToolBarUI.createFloatingWindow(JToolBar) * * @param toolbar an instance of {@code JToolBar} * @return an instance of {@code JFrame} * @see #createFloatingWindow */ protected JFrame createFloatingFrame(JToolBar toolbar) { Window window = SwingUtilities.getWindowAncestor(toolbar); @SuppressWarnings("serial") // anonymous class JFrame frame = new JFrame(toolbar.getName(), (window != null) ? window.getGraphicsConfiguration() : null) { // Override createRootPane() to automatically resize // the frame when contents change protected JRootPane createRootPane() { @SuppressWarnings("serial") // anonymous class JRootPane rootPane = new JRootPane() { private boolean packing = false; public void validate() { super.validate(); if (!packing) { packing = true; pack(); packing = false; } } }; rootPane.setOpaque(true); return rootPane; } }; frame.getRootPane().setName("ToolBar.FloatingFrame"); frame.setResizable(false); WindowListener wl = createFrameListener(); frame.addWindowListener(wl); return frame; } /** * Creates a window which contains the toolbar after it has been * dragged out from its container * * @param toolbar an instance of {@code JToolBar} * @return a {@code RootPaneContainer} object, containing the toolbar * @since 1.4 */ protected RootPaneContainer createFloatingWindow(JToolBar toolbar) { @SuppressWarnings("serial") // Superclass is not serializable across versions class ToolBarDialog extends JDialog { public ToolBarDialog(Frame owner, String title, boolean modal) { super(owner, title, modal); } public ToolBarDialog(Dialog owner, String title, boolean modal) { super(owner, title, modal); } // Override createRootPane() to automatically resize // the frame when contents change protected JRootPane createRootPane() { @SuppressWarnings("serial") // anonymous class JRootPane rootPane = new JRootPane() { private boolean packing = false; public void validate() { super.validate(); if (!packing) { packing = true; pack(); packing = false; } } }; rootPane.setOpaque(true); return rootPane; } } JDialog dialog; Window window = SwingUtilities.getWindowAncestor(toolbar); if (window instanceof Frame) { dialog = new ToolBarDialog((Frame)window, toolbar.getName(), false); } else if (window instanceof Dialog) { dialog = new ToolBarDialog((Dialog)window, toolbar.getName(), false); } else { dialog = new ToolBarDialog((Frame)null, toolbar.getName(), false); } dialog.getRootPane().setName("ToolBar.FloatingWindow"); dialog.setTitle(toolbar.getName()); dialog.setResizable(false); WindowListener wl = createFrameListener(); dialog.addWindowListener(wl); return dialog; } /** * Returns an instance of {@code DragWindow}. * * @param toolbar an instance of {@code JToolBar} * @return an instance of {@code DragWindow} */ protected DragWindow createDragWindow(JToolBar toolbar) { Window frame = null; if(toolBar != null) { Container p; for(p = toolBar.getParent() ; p != null && !(p instanceof Window) ; p = p.getParent()); if(p != null && p instanceof Window) frame = (Window) p; } if(floatingToolBar == null) { floatingToolBar = createFloatingWindow(toolBar); } if (floatingToolBar instanceof Window) frame = (Window) floatingToolBar; DragWindow dragWindow = new DragWindow(frame); return dragWindow; } /** * Returns a flag to determine whether rollover button borders * are enabled. * * @return true if rollover borders are enabled; false otherwise * @see #setRolloverBorders * @since 1.4 */ public boolean isRolloverBorders() { return rolloverBorders; } /** * Sets the flag for enabling rollover borders on the toolbar and it will * also install the appropriate border depending on the state of the flag. * * @param rollover if true, rollover borders are installed. * Otherwise non-rollover borders are installed * @see #isRolloverBorders * @since 1.4 */ public void setRolloverBorders( boolean rollover ) { rolloverBorders = rollover; if ( rolloverBorders ) { installRolloverBorders( toolBar ); } else { installNonRolloverBorders( toolBar ); } } /** * Installs rollover borders on all the child components of the JComponent. *

* This is a convenience method to call setBorderToRollover * for each child component. * * @param c container which holds the child components (usually a JToolBar) * @see #setBorderToRollover * @since 1.4 */ protected void installRolloverBorders ( JComponent c ) { // Put rollover borders on buttons Component[] components = c.getComponents(); for (Component component : components) { if (component instanceof JComponent) { ((JComponent) component).updateUI(); setBorderToRollover(component); } } } /** * Installs non-rollover borders on all the child components of the JComponent. * A non-rollover border is the border that is installed on the child component * while it is in the toolbar. *

* This is a convenience method to call setBorderToNonRollover * for each child component. * * @param c container which holds the child components (usually a JToolBar) * @see #setBorderToNonRollover * @since 1.4 */ protected void installNonRolloverBorders ( JComponent c ) { // Put non-rollover borders on buttons. These borders reduce the margin. Component[] components = c.getComponents(); for (Component component : components) { if (component instanceof JComponent) { ((JComponent) component).updateUI(); setBorderToNonRollover(component); } } } /** * Installs normal borders on all the child components of the JComponent. * A normal border is the original border that was installed on the child * component before it was added to the toolbar. *

* This is a convenience method to call setBorderNormal * for each child component. * * @param c container which holds the child components (usually a JToolBar) * @see #setBorderToNonRollover * @since 1.4 */ protected void installNormalBorders ( JComponent c ) { // Put back the normal borders on buttons Component[] components = c.getComponents(); for (Component component : components) { setBorderToNormal(component); } } /** * Sets the border of the component to have a rollover border which * was created by the {@link #createRolloverBorder} method. * * @param c component which will have a rollover border installed * @see #createRolloverBorder * @since 1.4 */ protected void setBorderToRollover(Component c) { if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton)c; Border border = borderTable.get(b); if (border == null || border instanceof UIResource) { borderTable.put(b, b.getBorder()); } // Only set the border if its the default border if (b.getBorder() instanceof UIResource) { b.setBorder(getRolloverBorder(b)); } rolloverTable.put(b, b.isRolloverEnabled()? Boolean.TRUE: Boolean.FALSE); b.setRolloverEnabled(true); } } /** * Returns a rollover border for the button. * * @param b the button to calculate the rollover border for * @return the rollover border * @see #setBorderToRollover * @since 1.6 */ protected Border getRolloverBorder(AbstractButton b) { return rolloverBorder; } /** * Sets the border of the component to have a non-rollover border which * was created by the {@link #createNonRolloverBorder} method. * * @param c component which will have a non-rollover border installed * @see #createNonRolloverBorder * @since 1.4 */ protected void setBorderToNonRollover(Component c) { if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton)c; Border border = borderTable.get(b); if (border == null || border instanceof UIResource) { borderTable.put(b, b.getBorder()); } // Only set the border if its the default border if (b.getBorder() instanceof UIResource) { b.setBorder(getNonRolloverBorder(b)); } rolloverTable.put(b, b.isRolloverEnabled()? Boolean.TRUE: Boolean.FALSE); b.setRolloverEnabled(false); } } /** * Returns a non-rollover border for the button. * * @param b the button to calculate the non-rollover border for * @return the non-rollover border * @see #setBorderToNonRollover * @since 1.6 */ protected Border getNonRolloverBorder(AbstractButton b) { if (b instanceof JToggleButton) { return nonRolloverToggleBorder; } else { return nonRolloverBorder; } } /** * Sets the border of the component to have a normal border. * A normal border is the original border that was installed on the child * component before it was added to the toolbar. * * @param c component which will have a normal border re-installed * @see #createNonRolloverBorder * @since 1.4 */ protected void setBorderToNormal(Component c) { if (c instanceof AbstractButton) { AbstractButton b = (AbstractButton)c; Border border = borderTable.remove(b); b.setBorder(border); Boolean value = rolloverTable.remove(b); if (value != null) { b.setRolloverEnabled(value.booleanValue()); } } } /** * Sets the floating location. * * @param x an X coordinate * @param y an Y coordinate */ public void setFloatingLocation(int x, int y) { floatingX = x; floatingY = y; } /** * Returns {@code true} if the {@code JToolBar} is floating * * @return {@code true} if the {@code JToolBar} is floating */ public boolean isFloating() { return floating; } /** * Sets the floating property. * * @param b {@code true} if the {@code JToolBar} is floating * @param p the position */ @SuppressWarnings("deprecation") public void setFloating(boolean b, Point p) { if (toolBar.isFloatable()) { boolean visible = false; Window ancestor = SwingUtilities.getWindowAncestor(toolBar); if (ancestor != null) { visible = ancestor.isVisible(); } if (dragWindow != null) dragWindow.setVisible(false); this.floating = b; if (floatingToolBar == null) { floatingToolBar = createFloatingWindow(toolBar); } if (b == true) { if (dockingSource == null) { dockingSource = toolBar.getParent(); dockingSource.remove(toolBar); } constraintBeforeFloating = calculateConstraint(); if ( propertyListener != null ) UIManager.addPropertyChangeListener( propertyListener ); floatingToolBar.getContentPane().add(toolBar,BorderLayout.CENTER); if (floatingToolBar instanceof Window) { ((Window)floatingToolBar).pack(); ((Window)floatingToolBar).setLocation(floatingX, floatingY); if (visible) { ((Window)floatingToolBar).show(); } else { ancestor.addWindowListener(new WindowAdapter() { public void windowOpened(WindowEvent e) { ((Window)floatingToolBar).show(); } }); } } } else { if (floatingToolBar == null) floatingToolBar = createFloatingWindow(toolBar); if (floatingToolBar instanceof Window) ((Window)floatingToolBar).setVisible(false); floatingToolBar.getContentPane().remove(toolBar); String constraint = getDockingConstraint(dockingSource, p); if (constraint == null) { constraint = BorderLayout.NORTH; } int orientation = mapConstraintToOrientation(constraint); setOrientation(orientation); if (dockingSource== null) dockingSource = toolBar.getParent(); if ( propertyListener != null ) UIManager.removePropertyChangeListener( propertyListener ); dockingSource.add(constraint, toolBar); } dockingSource.invalidate(); Container dockingSourceParent = dockingSource.getParent(); if (dockingSourceParent != null) dockingSourceParent.validate(); dockingSource.repaint(); } } private int mapConstraintToOrientation(String constraint) { int orientation = toolBar.getOrientation(); if ( constraint != null ) { if ( constraint.equals(BorderLayout.EAST) || constraint.equals(BorderLayout.WEST) ) orientation = JToolBar.VERTICAL; else if ( constraint.equals(BorderLayout.NORTH) || constraint.equals(BorderLayout.SOUTH) ) orientation = JToolBar.HORIZONTAL; } return orientation; } /** * Sets the tool bar's orientation. * * @param orientation the new orientation */ public void setOrientation(int orientation) { toolBar.setOrientation( orientation ); if (dragWindow !=null) dragWindow.setOrientation(orientation); } /** * Gets the color displayed when over a docking area * * @return the color displayed when over a docking area */ public Color getDockingColor() { return dockingColor; } /** * Sets the color displayed when over a docking area * * @param c the new color */ public void setDockingColor(Color c) { this.dockingColor = c; } /** * Gets the color displayed when over a floating area * * @return the color displayed when over a floating area */ public Color getFloatingColor() { return floatingColor; } /** * Sets the color displayed when over a floating area * * @param c the new color */ public void setFloatingColor(Color c) { this.floatingColor = c; } private boolean isBlocked(Component comp, Object constraint) { if (comp instanceof Container) { Container cont = (Container)comp; LayoutManager lm = cont.getLayout(); if (lm instanceof BorderLayout) { BorderLayout blm = (BorderLayout)lm; Component c = blm.getLayoutComponent(cont, constraint); return (c != null && c != toolBar); } } return false; } /** * Returns {@code true} if the {@code JToolBar} can dock at the given position. * * @param c a component * @param p a position * @return {@code true} if the {@code JToolBar} can dock at the given position */ public boolean canDock(Component c, Point p) { return (p != null && getDockingConstraint(c, p) != null); } private String calculateConstraint() { String constraint = null; LayoutManager lm = dockingSource.getLayout(); if (lm instanceof BorderLayout) { constraint = (String)((BorderLayout)lm).getConstraints(toolBar); } return (constraint != null) ? constraint : constraintBeforeFloating; } private String getDockingConstraint(Component c, Point p) { if (p == null) return constraintBeforeFloating; if (c.contains(p)) { dockingSensitivity = (toolBar.getOrientation() == JToolBar.HORIZONTAL) ? toolBar.getSize().height : toolBar.getSize().width; // North (Base distance on height for now!) if (p.y < dockingSensitivity && !isBlocked(c, BorderLayout.NORTH)) { return BorderLayout.NORTH; } // East (Base distance on height for now!) if (p.x >= c.getWidth() - dockingSensitivity && !isBlocked(c, BorderLayout.EAST)) { return BorderLayout.EAST; } // West (Base distance on height for now!) if (p.x < dockingSensitivity && !isBlocked(c, BorderLayout.WEST)) { return BorderLayout.WEST; } if (p.y >= c.getHeight() - dockingSensitivity && !isBlocked(c, BorderLayout.SOUTH)) { return BorderLayout.SOUTH; } } return null; } /** * The method is used to drag {@code DragWindow} during the {@code JToolBar} * is being dragged. * * @param position the relative to the {@code JTollBar} position * @param origin the screen position of {@code JToolBar} before dragging */ @SuppressWarnings("deprecation") protected void dragTo(Point position, Point origin) { if (toolBar.isFloatable()) { try { if (dragWindow == null) dragWindow = createDragWindow(toolBar); Point offset = dragWindow.getOffset(); if (offset == null) { Dimension size = toolBar.getPreferredSize(); offset = new Point(size.width/2, size.height/2); dragWindow.setOffset(offset); } Point global = new Point(origin.x+ position.x, origin.y+position.y); Point dragPoint = new Point(global.x- offset.x, global.y- offset.y); if (dockingSource == null) dockingSource = toolBar.getParent(); constraintBeforeFloating = calculateConstraint(); Point dockingPosition = dockingSource.getLocationOnScreen(); Point comparisonPoint = new Point(global.x-dockingPosition.x, global.y-dockingPosition.y); if (canDock(dockingSource, comparisonPoint)) { dragWindow.setBackground(getDockingColor()); String constraint = getDockingConstraint(dockingSource, comparisonPoint); int orientation = mapConstraintToOrientation(constraint); dragWindow.setOrientation(orientation); dragWindow.setBorderColor(dockingBorderColor); } else { dragWindow.setBackground(getFloatingColor()); dragWindow.setBorderColor(floatingBorderColor); dragWindow.setOrientation(toolBar.getOrientation()); } dragWindow.setLocation(dragPoint.x, dragPoint.y); if (dragWindow.isVisible() == false) { Dimension size = toolBar.getPreferredSize(); dragWindow.setSize(size.width, size.height); dragWindow.show(); } } catch ( IllegalComponentStateException e ) { } } } /** * The method is called at end of dragging to place the frame in either * its original place or in its floating frame. * * @param position the relative to the {@code JTollBar} position * @param origin the screen position of {@code JToolBar} before dragging */ protected void floatAt(Point position, Point origin) { if(toolBar.isFloatable()) { try { Point offset = dragWindow.getOffset(); if (offset == null) { offset = position; dragWindow.setOffset(offset); } Point global = new Point(origin.x+ position.x, origin.y+position.y); setFloatingLocation(global.x-offset.x, global.y-offset.y); if (dockingSource != null) { Point dockingPosition = dockingSource.getLocationOnScreen(); Point comparisonPoint = new Point(global.x-dockingPosition.x, global.y-dockingPosition.y); if (canDock(dockingSource, comparisonPoint)) { setFloating(false, comparisonPoint); } else { setFloating(true, null); } } else { setFloating(true, null); } dragWindow.setOffset(null); } catch ( IllegalComponentStateException e ) { } } } private Handler getHandler() { if (handler == null) { handler = new Handler(); } return handler; } /** * Returns an instance of {@code ContainerListener}. * * @return an instance of {@code ContainerListener} */ protected ContainerListener createToolBarContListener( ) { return getHandler(); } /** * Returns an instance of {@code FocusListener}. * * @return an instance of {@code FocusListener} */ protected FocusListener createToolBarFocusListener( ) { return getHandler(); } /** * Returns an instance of {@code PropertyChangeListener}. * * @return an instance of {@code PropertyChangeListener} */ protected PropertyChangeListener createPropertyListener() { return getHandler(); } /** * Returns an instance of {@code MouseInputListener}. * * @return an instance of {@code MouseInputListener} */ protected MouseInputListener createDockingListener( ) { getHandler().tb = toolBar; return getHandler(); } /** * Constructs a new instance of {@code WindowListener}. * * @return a new instance of {@code WindowListener} */ protected WindowListener createFrameListener() { return new FrameListener(); } /** * Paints the contents of the window used for dragging. * * @param g Graphics to paint to. * @throws NullPointerException is g is null * @since 1.5 */ protected void paintDragWindow(Graphics g) { g.setColor(dragWindow.getBackground()); int w = dragWindow.getWidth(); int h = dragWindow.getHeight(); g.fillRect(0, 0, w, h); g.setColor(dragWindow.getBorderColor()); g.drawRect(0, 0, w - 1, h - 1); } private static class Actions extends UIAction { private static final String NAVIGATE_RIGHT = "navigateRight"; private static final String NAVIGATE_LEFT = "navigateLeft"; private static final String NAVIGATE_UP = "navigateUp"; private static final String NAVIGATE_DOWN = "navigateDown"; public Actions(String name) { super(name); } public void actionPerformed(ActionEvent evt) { String key = getName(); JToolBar toolBar = (JToolBar)evt.getSource(); BasicToolBarUI ui = (BasicToolBarUI)BasicLookAndFeel.getUIOfType( toolBar.getUI(), BasicToolBarUI.class); if (NAVIGATE_RIGHT == key) { ui.navigateFocusedComp(EAST); } else if (NAVIGATE_LEFT == key) { ui.navigateFocusedComp(WEST); } else if (NAVIGATE_UP == key) { ui.navigateFocusedComp(NORTH); } else if (NAVIGATE_DOWN == key) { ui.navigateFocusedComp(SOUTH); } } } private class Handler implements ContainerListener, FocusListener, MouseInputListener, PropertyChangeListener { // // ContainerListener // public void componentAdded(ContainerEvent evt) { Component c = evt.getChild(); if (toolBarFocusListener != null) { c.addFocusListener(toolBarFocusListener); } if (isRolloverBorders()) { setBorderToRollover(c); } else { setBorderToNonRollover(c); } } public void componentRemoved(ContainerEvent evt) { Component c = evt.getChild(); if (toolBarFocusListener != null) { c.removeFocusListener(toolBarFocusListener); } // Revert the button border setBorderToNormal(c); } // // FocusListener // public void focusGained(FocusEvent evt) { Component c = evt.getComponent(); focusedCompIndex = toolBar.getComponentIndex(c); } public void focusLost(FocusEvent evt) { } // // MouseInputListener (DockingListener) // JToolBar tb; boolean isDragging = false; Point origin = null; public void mousePressed(MouseEvent evt) { if (!tb.isEnabled()) { return; } isDragging = false; } public void mouseReleased(MouseEvent evt) { if (!tb.isEnabled()) { return; } if (isDragging) { Point position = evt.getPoint(); if (origin == null) origin = evt.getComponent().getLocationOnScreen(); floatAt(position, origin); } origin = null; isDragging = false; } public void mouseDragged(MouseEvent evt) { if (!tb.isEnabled()) { return; } isDragging = true; Point position = evt.getPoint(); if (origin == null) { origin = evt.getComponent().getLocationOnScreen(); } dragTo(position, origin); } public void mouseClicked(MouseEvent evt) {} public void mouseEntered(MouseEvent evt) {} public void mouseExited(MouseEvent evt) {} public void mouseMoved(MouseEvent evt) {} // // PropertyChangeListener // public void propertyChange(PropertyChangeEvent evt) { String propertyName = evt.getPropertyName(); if (propertyName == "lookAndFeel") { toolBar.updateUI(); } else if (propertyName == "orientation") { // Search for JSeparator components and change it's orientation // to match the toolbar and flip it's orientation. Component[] components = toolBar.getComponents(); int orientation = ((Integer)evt.getNewValue()).intValue(); JToolBar.Separator separator; for (int i = 0; i < components.length; ++i) { if (components[i] instanceof JToolBar.Separator) { separator = (JToolBar.Separator)components[i]; if ((orientation == JToolBar.HORIZONTAL)) { separator.setOrientation(JSeparator.VERTICAL); } else { separator.setOrientation(JSeparator.HORIZONTAL); } Dimension size = separator.getSeparatorSize(); if (size != null && size.width != size.height) { // Flip the orientation. Dimension newSize = new Dimension(size.height, size.width); separator.setSeparatorSize(newSize); } } } } else if (propertyName == IS_ROLLOVER) { installNormalBorders(toolBar); setRolloverBorders(((Boolean)evt.getNewValue()).booleanValue()); } } } /** * The class listens for window events. */ protected class FrameListener extends WindowAdapter { public void windowClosing(WindowEvent w) { if (toolBar.isFloatable()) { if (dragWindow != null) dragWindow.setVisible(false); floating = false; if (floatingToolBar == null) floatingToolBar = createFloatingWindow(toolBar); if (floatingToolBar instanceof Window) ((Window)floatingToolBar).setVisible(false); floatingToolBar.getContentPane().remove(toolBar); String constraint = constraintBeforeFloating; if (toolBar.getOrientation() == JToolBar.HORIZONTAL) { if (constraint == "West" || constraint == "East") { constraint = "North"; } } else { if (constraint == "North" || constraint == "South") { constraint = "West"; } } if (dockingSource == null) dockingSource = toolBar.getParent(); if (propertyListener != null) UIManager.removePropertyChangeListener(propertyListener); dockingSource.add(toolBar, constraint); dockingSource.invalidate(); Container dockingSourceParent = dockingSource.getParent(); if (dockingSourceParent != null) dockingSourceParent.validate(); dockingSource.repaint(); } } } /** * The class listens for component events. */ protected class ToolBarContListener implements ContainerListener { // NOTE: This class exists only for backward compatibility. All // its functionality has been moved into Handler. If you need to add // new functionality add it to the Handler, but make sure this // class calls into the Handler. public void componentAdded( ContainerEvent e ) { getHandler().componentAdded(e); } public void componentRemoved( ContainerEvent e ) { getHandler().componentRemoved(e); } } /** * The class listens for focus events. */ protected class ToolBarFocusListener implements FocusListener { // NOTE: This class exists only for backward compatibility. All // its functionality has been moved into Handler. If you need to add // new functionality add it to the Handler, but make sure this // class calls into the Handler. public void focusGained( FocusEvent e ) { getHandler().focusGained(e); } public void focusLost( FocusEvent e ) { getHandler().focusLost(e); } } /** * The class listens for property changed events. */ protected class PropertyListener implements PropertyChangeListener { // NOTE: This class exists only for backward compatibility. All // its functionality has been moved into Handler. If you need to add // new functionality add it to the Handler, but make sure this // class calls into the Handler. public void propertyChange( PropertyChangeEvent e ) { getHandler().propertyChange(e); } } /** * This class should be treated as a "protected" inner class. * Instantiate it only within subclasses of BasicToolBarUI. */ public class DockingListener implements MouseInputListener { // NOTE: This class exists only for backward compatibility. All // its functionality has been moved into Handler. If you need to add // new functionality add it to the Handler, but make sure this // class calls into the Handler. /** * The instance of {@code JToolBar}. */ protected JToolBar toolBar; /** * {@code true} if the {@code JToolBar} is being dragged. */ protected boolean isDragging = false; /** * The origin point. */ protected Point origin = null; /** * Constructs a new instance of {@code DockingListener}. * * @param t an instance of {@code JToolBar} */ public DockingListener(JToolBar t) { this.toolBar = t; getHandler().tb = t; } public void mouseClicked(MouseEvent e) { getHandler().mouseClicked(e); } public void mousePressed(MouseEvent e) { getHandler().tb = toolBar; getHandler().mousePressed(e); isDragging = getHandler().isDragging; } public void mouseReleased(MouseEvent e) { getHandler().tb = toolBar; getHandler().isDragging = isDragging; getHandler().origin = origin; getHandler().mouseReleased(e); isDragging = getHandler().isDragging; origin = getHandler().origin; } public void mouseEntered(MouseEvent e) { getHandler().mouseEntered(e); } public void mouseExited(MouseEvent e) { getHandler().mouseExited(e); } public void mouseDragged(MouseEvent e) { getHandler().tb = toolBar; getHandler().origin = origin; getHandler().mouseDragged(e); isDragging = getHandler().isDragging; origin = getHandler().origin; } public void mouseMoved(MouseEvent e) { getHandler().mouseMoved(e); } } /** * The window which appears during dragging the {@code JToolBar}. */ @SuppressWarnings("serial") // Same-version serialization only protected class DragWindow extends Window { Color borderColor = Color.gray; int orientation = toolBar.getOrientation(); Point offset; // offset of the mouse cursor inside the DragWindow DragWindow(Window w) { super(w); } /** * Returns the orientation of the toolbar window when the toolbar is * floating. The orientation is either one of JToolBar.HORIZONTAL * or JToolBar.VERTICAL. * * @return the orientation of the toolbar window * @since 1.6 */ public int getOrientation() { return orientation; } /** * Sets the orientation. * * @param o the new orientation */ public void setOrientation(int o) { if(isShowing()) { if (o == this.orientation) return; this.orientation = o; Dimension size = getSize(); setSize(new Dimension(size.height, size.width)); if (offset!=null) { if( BasicGraphicsUtils.isLeftToRight(toolBar) ) { setOffset(new Point(offset.y, offset.x)); } else if( o == JToolBar.HORIZONTAL ) { setOffset(new Point( size.height-offset.y, offset.x)); } else { setOffset(new Point(offset.y, size.width-offset.x)); } } repaint(); } } /** * Returns the offset. * * @return the offset */ public Point getOffset() { return offset; } /** * Sets the offset. * * @param p the new offset */ public void setOffset(Point p) { this.offset = p; } /** * Sets the border color. * * @param c the new border color */ public void setBorderColor(Color c) { if (this.borderColor == c) return; this.borderColor = c; repaint(); } /** * Returns the border color. * * @return the border color */ public Color getBorderColor() { return this.borderColor; } public void paint(Graphics g) { paintDragWindow(g); // Paint the children super.paint(g); } public Insets getInsets() { return new Insets(1,1,1,1); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy