Grinding6.java
Appearance
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; }