home *** CD-ROM | disk | FTP | other *** search
Java Source | 1997-06-01 | 10.2 KB | 293 lines |
- package GUITools;
- import GUITools.ImageButton;
-
- import java.AWT.*;
- import java.AWT.event.*;
- import java.util.Vector;
- /**
- * Dockable toolbar class written by Shai Almog 1996.
- * revised for JDK 1.1.1 in 4/97.
- * The sorce is in the public domain and may be modified and used freely.
- * It is not a requirment but I would consider it good manners if you credit me
- * and EDM/2 (www.edm2.com) in applications in which this code was used ;-)
- * The Dockable toolbar class creats a toolbar container that can be torn
- * off the Frame holding it and left to hover above it.
- * It's based on the panel and Window classes and it must be put
- * on a frame.
- * A problem with the Dockable toolbar is the way different implementations
- * of the JDK treat the Window class. This creates a highly an portable
- * implementation, the solution was to abstract everything and hope that
- * a future implementation of the JDK solves this problem.
- **/
-
- public class DockableToolbar extends
- java.AWT.Panel implements ActionListener, MouseMotionListener, MouseListener
- {
- public DockableToolbar(Frame Owner) // Owner is the component who own's the Toolbar.
- {
- this.Owner = Owner; // This is an easy trick to avoid confusion with parameters
- // This way you don't have to invent a name for every parameter.
- setLayout(new FlowLayout()); // The flow layout just put's the Components
- // one after the other as best as it can. No better is needed here.
- addToolbarToOwner(); // This method will add the panel and the frame to
- addMouseMotionListener(this);
- addMouseListener(this);
- }
-
- /**
- * This method gets called when an event occurs in the Components we
- * are listenting too, since we are listening to the Container and all
- * of the buttons all of their events reach us.
- * I'd like too seprate the event handeling here from the implementation
- * but it's not practical due to it's heavyconnection to the Component.
- **/
- public void actionPerformed(ActionEvent E)
- {
- if(E.getSource() instanceof Button) // If the event source is a button
- sendEvent(whichButtonGotPressed((Button)E.getSource()));
- }
-
- /**
- * This method allows an object to listen to events dispatched by the toolbar,
- * in a similar way to listening to events dispatched by buttons.
- **/
- public void addActionListener(ActionListener listener)
- {
- listOfActionListeners.addElement(listener);
- }
-
- public void addButton(Button B) // This method adds a button to the Toolbar.
- {
- add(B);
- listOfButtons.addElement((Object)B);
- B.addActionListener(this); // Listening to action events on the button (mouse clicks).
- B.addMouseMotionListener(this); // Listening to mouse motion events on the
- // button (for Tooltips).
- B.addMouseListener(this); // Listening to mouse events on the
- // button (for dropping dragged Toolbars).
- }
-
- public void addButton(String caption) // Creats a Button with the label = caption.
- {
- addButton(new Button(caption));
- }
-
- private void addToolbarToOwner() // This method will add the panel to the
- // Toolbar Container.
- {
- Owner.add(this);
- }
-
- /**
- * This method detaches the toolbar, and leaves it hanging above the Frame.
- **/
- public void detachToolbar()
- {
- if (detachedToolbar != null)
- {
- dockToolbar();
- return;
- }
- detachedToolbar = new Window(Owner); // Creating the Window that will hold the Toolbar.
- detachedToolbar.setLayout(new BorderLayout()); // We will only have one
- // component in the frame (the Panel), but it's best to do it this way.
- detachedToolbar.add("South", this); // We add this (the Panel) to the frame yet keep
- // it hidden.
- Owner.remove(this); // Removing the Panel from the Toolbar.
-
- systemSpecificToolbarCalibration(); // This is the part that initializes the Window.
- // I had a rough time with it ,so I dumped it into a seprate method so it can
- // be modified with ease.
-
- detachedToolbar.show(); // Show the hovering Toolbar.
- Owner.pack(); // Arrange the components in the original Container.
- }
-
- /**
- * This method reattaches the toolbar to the owner frame.
- **/
- public void dockToolbar()
- {
- if (detachedToolbar == null)
- {
- detachToolbar();
- return;
- }
- Owner.add(this);
- Owner.pack(); // Sort the Components in the Container.
- detachedToolbar.removeAll();
- detachedToolbar.dispose(); // Destroy the hovering window.
- detachedToolbar = null; // this is so we can tell if the toolbar is docked.
- }
-
- public boolean isDocked() // This method returns true if the toolbar is not hovering.
- {
- return (detachedToolbar == null);
- }
-
- public void mouseClicked(MouseEvent e)
- {
- // This method must be implemented to support the MouseListener interface.
- }
-
- /**
- * This method is called in an event of a mouse drag.
- * It can happen for 2 reasons:
- * 1. The Toolbar is torn from place.
- * 2. The Toolbar is being dragged, remember the Window class is not
- * like the Frame class, it cannot be dragged by default.
- **/
- public void mouseDragged(MouseEvent e)
- { // We use this method to detach the toolbar and to move it.
- if (detachedToolbar == null) // If the toolbar is docked.
- detachToolbar(); // Then it's being torn off, detach it.
- else // If the toolbar is detached then we are trying to drag it.
- {
- // We comute the X and Y where to drag it too.
- // This is not simple since the X and Y we are give is relative to the
- // Component which is the window.
- if(lastYLocationOnDrag == -1)
- {
- lastYLocationOnDrag = e.getY();
- lastXLocationOnDrag = e.getX();
- }
- else
- {
- int x = detachedToolbar.getLocation().x + e.getX() - lastXLocationOnDrag,
- y = detachedToolbar.getLocation().y + e.getY() - lastYLocationOnDrag;
- lastYLocationOnDrag = -1;
- lastXLocationOnDrag = -1;
- detachedToolbar.setLocation(x,y);
- repaint();
- }
- }
- }
-
- public void mouseEntered(MouseEvent e)
- {
- // This method must be implemented to support the MouseMotionListener interface.
- }
-
- public void mouseExited(MouseEvent e)
- {
- // This method must be implemented to support the MouseMotionListener interface.
- }
-
- public void mouseMoved(MouseEvent e)
- {
- // This method must be implemented to support the MouseMotionListener interface.
- }
-
- public void mousePressed(MouseEvent
- e)
- {
- // This method must be implemented to support the MouseListener interface.
- }
-
- /**
- * This method could mean the end of a drag operation. So here we use it to
- * drop the Toolbar, if it's being dragged.
- */
- public void mouseReleased(MouseEvent e)
- {
- if(lastYLocationOnDrag != -1)
- {
- int x = detachedToolbar.getLocation().x + e.getX() - lastXLocationOnDrag,
- y = detachedToolbar.getLocation().y + e.getY() - lastYLocationOnDrag;
- lastYLocationOnDrag = -1;
- lastXLocationOnDrag = -1;
- detachedToolbar.setLocation(x,y);
- repaint();
- }
- }
-
- /**
- * This method sends the button pressed event to all listeners.
- * It's needed so that an application can listen to the toolbar without
- * maintaining logic for all the Buttons on it.
- **/
- private void sendEvent(int idOfTheButtonPressed)
- {
- ActionListener currentListener;
- ActionEvent E = new
- ActionEvent(listOfButtons.elementAt(idOfTheButtonPressed),
- ActionEvent.ACTION_PERFORMED,
- Integer.toString(idOfTheButtonPressed));
- for (int counter = 0; counter < listOfActionListeners.size(); counter++)
- {
- currentListener = (ActionListener)listOfActionListeners.elementAt(counter);
- currentListener.actionPerformed(E);
- }
- }
-
- /**
- * This method is used by the detachToolbar method to handle the Window class.
- * The reason this is in a seprate class is to abstaract the incompatible behavior
- * among JDK versions.
- **/
- private void systemSpecificToolbarCalibration()
- {
- detachedToolbar.pack();
- Dimension windowSize = detachedToolbar.getSize(),
- buttonSize = ((Component)listOfButtons.elementAt(0)).getSize();
- detachedToolbarTitleBar = new ToolbarTitleBar(windowSize.width,TOOLBAR_TITLEBAR_HEIGHT);
-
- detachedToolbar.add("North", detachedToolbarTitleBar);
- detachedToolbar.pack();
- }
-
- /**
- * This method was originally used to send the button pressed events, but now
- * I use it to check the button offset for a button ID.
- **/
- private int whichButtonGotPressed(Button B)
- { // This method returns the Buttons offset in the vector.
- for (int counter = 0; counter < listOfButtons.size() ; counter++)
- if(listOfButtons.elementAt(counter) == B)
- return(counter);
- return(-1);
- }
-
- private Window detachedToolbar = null; // This is the hovering Toolbar.
- private ToolbarTitleBar detachedToolbarTitleBar; // This is the Tile bar of the Toolbar.
- private Vector listOfTooltips = new Vector(); // This is a list of the Tooltip strings.
- private Vector listOfActionListeners = new Vector(); // This is a list of the classes
- // that listen to toolbar events.
- private Vector listOfButtons = new Vector(); // This is a list of the buttons.
- private Frame Owner; // This is the Frame the Toolbar is located on.
- private int lastXLocationOnDrag = -1; // These two variables are used for
- // dragging the toolbar.
- private int lastYLocationOnDrag = -1;
- private static final int TOOLBAR_TITLEBAR_HEIGHT = 5; // This is the height
- // of the toolbars title bar.
- }
-
-
-
- /**
- * This class is for internal use only. It paints the title on top of
- * the detached window.
- * The Window class is just a Canvas with no title to grab on to and this
- * canvas makes it look similar.
- **/
- class ToolbarTitleBar extends Canvas
- {
- ToolbarTitleBar(int width, int height)
- {
- super();
- setSize(width,height); // Canvas on the window top in 3 pixel hight.
- this.height = height;
- this.width = width;
- }
-
- public void paint(Graphics g)
- {
- g.setColor(SystemColor.activeCaption); // The SystemColor class contains
- // colors specific to this system.
- g.fillRect(0,0,width,i);
- }
-
- private int height;
- private int width;
- }
-