/* * @(#)BasicToolBarUI.java 1.59 00/02/02 * * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. * * This software is the proprietary information of Sun Microsystems, Inc. * Use is subject to license terms. * */ package iiuf.swing; import javax.swing.*; import javax.swing.event.*; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Frame; import java.awt.Graphics; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Window; import java.awt.event.*; import java.awt.IllegalComponentStateException; import java.beans.*; import javax.swing.border.*; import javax.swing.plaf.*; import javax.swing.plaf.basic.BasicToolBarUI; /** JWindow based ToolBarUI. based on sun's BasicToolBarUI<p> A Basic L&F implementation of ToolBarUI. This implementation is a "combined" view/controller. <p> (c) 2001, DIUF<p> @author $Author: ohitz $ @author Georges Saab @author Jeff Shapiro @version $Name: $ $Revision: 1.1 $ */ public class JWindowToolBarUI extends BasicToolBarUI implements SwingConstants { protected JToolBar toolBar; private boolean floating; private int floatingX; private int floatingY; private JWindow floatingFrame; protected DragWindow dragWindow; private Container dockingSource; protected int focusedCompIndex = -1; protected Color dockingColor = null; protected Color floatingColor = null; protected Color dockingBorderColor = null; protected Color floatingBorderColor = null; protected MouseInputListener dockingListener; protected PropertyChangeListener propertyListener; protected ContainerListener toolBarContListener; protected FocusListener toolBarFocusListener; /** * 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. */ 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. */ 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. */ 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. */ protected KeyStroke rightKey; private static String FOCUSED_COMP_INDEX = "JToolBar.focusedCompIndex"; public static ComponentUI createUI( JComponent c ) { return new JWindowToolBarUI(); } public void installUI( JComponent c ) { toolBar = (JToolBar) c; // Set defaults installDefaults(); installComponents(); installListeners(); installKeyboardActions(); // Initialize instance vars floating = false; floatingX = floatingY = 0; floatingFrame = null; setOrientation( toolBar.getOrientation() ); c.setOpaque(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() == true) setFloating(false, null); floatingFrame = null; dragWindow = null; dockingSource = null; c.putClientProperty( FOCUSED_COMP_INDEX, new Integer( focusedCompIndex ) ); } 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"); } protected void uninstallDefaults( ) { LookAndFeel.uninstallBorder(toolBar); dockingColor = null; floatingColor = null; dockingBorderColor = null; floatingBorderColor = null; } protected void installComponents( ) { } protected void uninstallComponents( ) { } protected void installListeners( ) { dockingListener = createDockingListener( ); if ( dockingListener != null ) { toolBar.addMouseMotionListener( dockingListener ); toolBar.addMouseListener( dockingListener ); } propertyListener = createPropertyListener(); // added in setFloating 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 ( int i = 0; i < components.length; ++i ) { components[ i ].addFocusListener( toolBarFocusListener ); } } } protected void uninstallListeners( ) { if ( dockingListener != null ) { toolBar.removeMouseMotionListener(dockingListener); toolBar.removeMouseListener(dockingListener); dockingListener = null; } if ( propertyListener != null ) { 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 ( int i = 0; i < components.length; ++i ) { components[ i ].removeFocusListener( toolBarFocusListener ); } toolBarFocusListener = null; } } protected void installKeyboardActions( ) { InputMap km = getInputMap(JComponent. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); SwingUtilities.replaceUIInputMap(toolBar, JComponent. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, km); ActionMap am = getActionMap(); if (am != null) { SwingUtilities.replaceUIActionMap(toolBar, am); } } InputMap getInputMap(int condition) { if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) { return (InputMap)UIManager.get("ToolBar.ancestorInputMap"); } return null; } ActionMap getActionMap() { ActionMap map = (ActionMap)UIManager.get("ToolBar.actionMap"); if (map == null) { map = createActionMap(); if (map != null) { UIManager.put("ToolBar.actionMap", map); } } return map; } ActionMap createActionMap() { ActionMap map = new ActionMapUIResource(); map.put("navigateRight", new RightAction()); map.put("navigateLeft", new LeftAction()); map.put("navigateUp", new UpAction()); map.put("navigateDown", new DownAction()); return map; } protected void uninstallKeyboardActions( ) { SwingUtilities.replaceUIActionMap(toolBar, null); SwingUtilities.replaceUIInputMap(toolBar, JComponent. WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null); } 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.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.requestFocus(); break; } } break; default: break; } } protected JWindow _createFloatingFrame(JToolBar toolbar) { JWindow frame = new JWindow() { public void paint(Graphics g) { super.paint(g); g.setColor(Color.black); g.drawRect(0, 0, getWidth() - 1, getHeight() - 1); } }; WindowListener wl = createFrameListener(); frame.addWindowListener(wl); return frame; } protected DragWindow _createDragWindow(JToolBar toolbar) { Window frame = null; if(toolBar != null) { Container p; for(p = toolBar.getParent() ; p != null && !(p instanceof Frame) ; p = p.getParent()); if(p != null && p instanceof Frame) frame = (Frame) p; } if(floatingFrame == null) { floatingFrame = _createFloatingFrame(toolBar); } frame = floatingFrame; DragWindow dragWindow = new DragWindow(frame); return dragWindow; } public Dimension getMinimumSize(JComponent c) { return getPreferredSize(c); } public Dimension getPreferredSize(JComponent c) { return null; } public Dimension getMaximumSize(JComponent c) { return getPreferredSize(c); } public void setFloatingLocation(int x, int y) { floatingX = x; floatingY = y; } public boolean isFloating() { return floating; } public void setFloating(boolean b, Point p) { if (toolBar.isFloatable() == true) { if (dragWindow != null) dragWindow.setVisible(false); this.floating = b; if (b == true) { if (dockingSource == null) { dockingSource = toolBar.getParent(); dockingSource.remove(toolBar); } if ( propertyListener != null ) UIManager.addPropertyChangeListener( propertyListener ); if (floatingFrame == null) floatingFrame = _createFloatingFrame(toolBar); floatingFrame.getContentPane().add(toolBar,BorderLayout.CENTER); floatingFrame.pack(); floatingFrame.setLocation(floatingX, floatingY); floatingFrame.show(); } else { if (floatingFrame == null) floatingFrame = _createFloatingFrame(toolBar); floatingFrame.setVisible(false); floatingFrame.getContentPane().remove(toolBar); String constraint = getDockingConstraint(dockingSource, p); 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; } public void setOrientation(int orientation) { if(orientation == toolBar.getOrientation()) return; toolBar.setOrientation(orientation); if(dragWindow != null) dragWindow.setOrientation(orientation); if(floatingFrame != null) { if(floatingFrame.isShowing()) { floatingFrame.pack(); } } } /** * Gets the color displayed when over a docking area */ public Color getDockingColor() { return dockingColor; } /** * Sets the color displayed when over a docking area */ public void setDockingColor(Color c) { this.dockingColor = c; } /** * Gets the color displayed when over a floating area */ public Color getFloatingColor() { return floatingColor; } /** * Sets the color displayed when over a floating area */ public void setFloatingColor(Color c) { this.floatingColor = c; } public boolean canDock(Component c, Point p) { // System.out.println("Can Dock: " + p); return c.contains(p); } private String getDockingConstraint(Component c, Point p) { String result = BorderLayout.NORTH; boolean trBL = p.y * c.getWidth() < p.x * c.getHeight(); boolean tlBR = p.y < c.getHeight() + (p.x * -(c.getHeight()) / c.getWidth()); if(trBL && tlBR) result = BorderLayout.NORTH; if(trBL && !tlBR) result = BorderLayout.EAST; if(!trBL && tlBR) result = BorderLayout.WEST; if(!trBL && !tlBR) result = BorderLayout.SOUTH; // System.out.println(result); return result; } protected void dragTo(Point position, Point offset_, Point origin) { if (toolBar.isFloatable() == true) { try { if(dragWindow == null) { dragWindow = _createDragWindow(toolBar); } Point offset = dragWindow.getOffset(); if(offset == null) { Dimension size = toolBar.getPreferredSize(); offset = offset_; if(dragWindow.getWidth() > 0 && offset.x > dragWindow.getWidth()) offset.x = dragWindow.getWidth() / 2; if(dragWindow.getHeight() > 0 &&offset.y > dragWindow.getHeight()) offset.y = dragWindow.getHeight() / 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(); 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.setLocation(dragPoint.x, dragPoint.y); if (dragWindow.isVisible() == false) { Dimension size = toolBar.getPreferredSize(); dragWindow.orientation = toolBar.getOrientation(); dragWindow.setSize(size.width, size.height); dragWindow.show(); } } catch ( IllegalComponentStateException e ) { } } } protected void floatAt(Point position, Point origin) { if(toolBar.isFloatable() == true) { 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 ) { } } } protected ContainerListener createToolBarContListener( ) { return new ToolBarContListener( ); } protected FocusListener createToolBarFocusListener( ) { return new ToolBarFocusListener( ); } protected PropertyChangeListener createPropertyListener() { return new PropertyListener(); } protected MouseInputListener createDockingListener( ) { return new DockingListener(toolBar); } protected WindowListener createFrameListener() { return new FrameListener(); } // The private inner classes below should be changed to protected the // next time API changes are allowed. private static abstract class KeyAction extends AbstractAction { public boolean isEnabled() { return true; } } private static class RightAction extends KeyAction { public void actionPerformed(ActionEvent e) { JToolBar toolBar = (JToolBar)e.getSource(); JWindowToolBarUI ui = (JWindowToolBarUI)toolBar.getUI(); ui.navigateFocusedComp(EAST); } } private static class LeftAction extends KeyAction { public void actionPerformed(ActionEvent e) { JToolBar toolBar = (JToolBar)e.getSource(); JWindowToolBarUI ui = (JWindowToolBarUI)toolBar.getUI(); ui.navigateFocusedComp(WEST); } } private static class UpAction extends KeyAction { public void actionPerformed(ActionEvent e) { JToolBar toolBar = (JToolBar)e.getSource(); JWindowToolBarUI ui = (JWindowToolBarUI)toolBar.getUI(); ui.navigateFocusedComp(NORTH); } } private static class DownAction extends KeyAction { public void actionPerformed(ActionEvent e) { JToolBar toolBar = (JToolBar)e.getSource(); JWindowToolBarUI ui = (JWindowToolBarUI)toolBar.getUI(); ui.navigateFocusedComp(SOUTH); } } protected class FrameListener extends WindowAdapter { public void windowClosing(WindowEvent w) { setFloating(false, null); } } protected class ToolBarContListener implements ContainerListener { public void componentAdded( ContainerEvent e ) { Component c = e.getChild(); if ( toolBarFocusListener != null ) { c.addFocusListener( toolBarFocusListener ); } } public void componentRemoved( ContainerEvent e ) { Component c = e.getChild(); if ( toolBarFocusListener != null ) { c.removeFocusListener( toolBarFocusListener ); } } } // end class ToolBarContListener protected class ToolBarFocusListener implements FocusListener { public void focusGained( FocusEvent e ) { Component c = e.getComponent(); focusedCompIndex = toolBar.getComponentIndex( c ); } public void focusLost( FocusEvent e ) { } } // end class ToolBarFocusListener protected class PropertyListener implements PropertyChangeListener { public void propertyChange( PropertyChangeEvent e ) { if ( e.getPropertyName().equals("lookAndFeel") ) { toolBar.updateUI(); } } } /** * This inner class is marked "public" due to a compiler bug. * This class should be treated as a "protected" inner class. * Instantiate it only within subclasses of JWindowToolBarUI. */ public class DockingListener implements MouseInputListener { protected JToolBar toolBar; protected boolean isDragging = false; protected Point origin = null; protected Point offset = null; public DockingListener(JToolBar t) { this.toolBar = t; } public void mouseClicked(MouseEvent e) { if(e.getClickCount() == 2) { if(toolBar.getOrientation() == VERTICAL) setOrientation(HORIZONTAL); else if(toolBar.getOrientation() == HORIZONTAL) setOrientation(VERTICAL); } } public void mousePressed(MouseEvent e) { if (!toolBar.isEnabled()) { return; } isDragging = false; offset = e.getPoint(); } public void mouseReleased(MouseEvent e) { if (!toolBar.isEnabled()) { return; } if (isDragging == true) { Point position = e.getPoint(); if (origin == null) origin = e.getComponent().getLocationOnScreen(); floatAt(position, origin); } origin = null; isDragging = false; } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mouseDragged(MouseEvent e) { if (!toolBar.isEnabled()) { return; } isDragging = true; Point position = e.getPoint(); if (origin == null) origin = e.getComponent().getLocationOnScreen(); dragTo(position, offset, origin); } public void mouseMoved(MouseEvent e) { } } protected class DragWindow extends Window { Color borderColor = Color.gray; int orientation = toolBar.getOrientation(); Point offset; // offset of the mouse cursor inside the DragWindow Dimension oh; Dimension ov; DragWindow(Window f) { super(f); } public void setOrientation(int o) { if (o == this.orientation) return; this.orientation = o; Dimension size; int ot = toolBar.getOrientation(); if(o == VERTICAL) { if(ov == null) { toolBar.setOrientation(VERTICAL); ov = toolBar.getPreferredSize(); } size = ov; } else { if(oh == null) { toolBar.setOrientation(HORIZONTAL); oh = toolBar.getPreferredSize(); } size = oh; } toolBar.setOrientation(ot); setSize(size); if(isShowing()) { if (offset!=null) { if( toolBar.getComponentOrientation().isLeftToRight() ) { setOffset(new Point(Math.min(offset.y, size.width - 5), Math.min(offset.x, size.height - 5))); } else if( o == JToolBar.HORIZONTAL ) { setOffset(new Point(size.height-offset.y, Math.min(offset.x, size.height - 5))); } else { setOffset(new Point(Math.min(offset.y, size.width - 5), size.width-offset.x)); } } repaint(); } } public Point getOffset() { return offset; } public void setOffset(Point p) { this.offset = p; } public void setBorderColor(Color c) { if (this.borderColor == c) return; this.borderColor = c; repaint(); } public Color getBorderColor() { return this.borderColor; } public void paint(Graphics g) { Color temp = g.getColor(); g.setColor(getBackground()); Dimension size = getSize(); g.fillRect(0,0,size.width, size.height); g.setColor(getBorderColor()); g.drawRect(0,0,size.width-1, size.height-1); g.setColor(temp); super.paint(g); } public Insets getInsets() { return new Insets(1,1,1,1); } } } /* $Log: JWindowToolBarUI.java,v $ Revision 1.1 2002/07/11 12:09:52 ohitz Initial checkin Revision 1.4 2001/03/05 17:55:07 schubige Still working on soundium properties panel Revision 1.3 2001/03/05 07:46:43 schubige Working on soundium properties panel, some sourcewatch extensions. Revision 1.2 2001/03/02 17:51:16 schubige Enhanced sourcewatch and worked on soundium properties panel Revision 1.1 2001/03/01 13:29:22 schubige interim checkin for soundium */