home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / os2 / edm2 / 0506 / grinding6.java < prev    next >
Encoding:
Java Source  |  1997-06-01  |  10.2 KB  |  293 lines

  1. package GUITools;
  2. import GUITools.ImageButton;
  3.  
  4. import java.AWT.*;
  5. import java.AWT.event.*;
  6. import java.util.Vector;
  7. /**
  8.  * Dockable toolbar class written by Shai Almog 1996.
  9.  * revised for JDK 1.1.1 in 4/97.
  10.  * The sorce is in the public domain and may be modified and used freely.
  11.  * It is not a requirment but I would consider it good manners if you credit me
  12.  * and EDM/2 (www.edm2.com) in applications in which this code was used ;-)
  13.  * The Dockable toolbar class creats a toolbar container that can be torn
  14.  * off the Frame holding it and left to hover above it.
  15.  * It's based on the panel and Window classes and it must be put
  16.  * on a frame.
  17.  * A problem with the Dockable toolbar is the way different implementations
  18.  * of the JDK treat the Window class. This creates a highly an portable
  19.  * implementation, the solution was to abstract everything and hope that
  20.  * a future implementation of the JDK solves this problem.
  21. **/
  22.  
  23. public class DockableToolbar extends
  24. java.AWT.Panel implements ActionListener, MouseMotionListener, MouseListener
  25. {
  26.  public DockableToolbar(Frame Owner) // Owner is the component who own's the Toolbar.
  27.  {
  28.   this.Owner = Owner; // This is an easy trick to avoid confusion with parameters
  29.           // This way you don't have to invent a name for every parameter.
  30.   setLayout(new FlowLayout()); // The flow layout just put's the  Components
  31.          // one after the other as best as it can. No better is needed here.
  32.   addToolbarToOwner(); // This method will add the panel and the frame to
  33.   addMouseMotionListener(this);
  34.   addMouseListener(this);
  35.  }
  36.  
  37.  /**
  38.   * This method gets called when an event occurs in the Components we
  39.   * are listenting too, since we are listening to the Container and all
  40.   * of the buttons all of their events reach us.
  41.   * I'd like too seprate the event handeling here from the implementation
  42.   * but it's not practical due to it's heavyconnection to the Component.
  43.  **/
  44.  public void actionPerformed(ActionEvent E)
  45.  {
  46.   if(E.getSource() instanceof Button) // If the event source is a button
  47.    sendEvent(whichButtonGotPressed((Button)E.getSource()));
  48.  }
  49.  
  50.  /**
  51.   * This method allows an object to listen to events dispatched by the toolbar,
  52.   * in a similar way to listening to events dispatched by buttons.
  53.  **/
  54.  public void addActionListener(ActionListener listener)
  55.  {
  56.   listOfActionListeners.addElement(listener);
  57.  }
  58.  
  59.  public void addButton(Button B) // This method adds a button to the Toolbar.
  60.  {
  61.   add(B);
  62.   listOfButtons.addElement((Object)B);
  63.   B.addActionListener(this); // Listening to action events on the button (mouse clicks).
  64.   B.addMouseMotionListener(this); // Listening to mouse motion events on the
  65.                                   // button (for Tooltips).
  66.   B.addMouseListener(this); // Listening to mouse events on the
  67.                             // button (for dropping dragged Toolbars).
  68.  }
  69.  
  70.  public void addButton(String caption) // Creats a Button with the label = caption.
  71.  {
  72.   addButton(new Button(caption));
  73.  }
  74.  
  75.  private void addToolbarToOwner() // This method will add the panel to the
  76.                                   // Toolbar Container.
  77.  {
  78.   Owner.add(this);
  79.  }
  80.  
  81.  /**
  82.   * This method detaches the toolbar, and leaves it hanging above the Frame.
  83.  **/
  84.  public void detachToolbar()
  85.  {
  86.    if (detachedToolbar != null)
  87.    {
  88.         dockToolbar();
  89.         return;
  90.    }
  91.   detachedToolbar = new Window(Owner); // Creating the Window that will hold the Toolbar.
  92.   detachedToolbar.setLayout(new BorderLayout()); // We will only have one
  93.      // component in the frame (the Panel), but it's best to do it this way.
  94.   detachedToolbar.add("South", this); // We add this (the Panel) to the frame yet keep
  95.                                       // it hidden.
  96.   Owner.remove(this); // Removing the Panel from the Toolbar.
  97.  
  98.   systemSpecificToolbarCalibration(); // This is the part that initializes the Window.
  99.     // I had a rough time with it ,so I dumped it into a seprate method so it can
  100.     // be modified with ease.
  101.  
  102.   detachedToolbar.show(); // Show the hovering Toolbar.
  103.   Owner.pack(); // Arrange the components in the original Container.
  104.  }
  105.  
  106.  /**
  107.   * This method reattaches the toolbar to the owner frame.
  108.  **/
  109.  public void dockToolbar()
  110.  {
  111.   if (detachedToolbar == null)
  112.   {
  113.     detachToolbar();
  114.     return;
  115.   }
  116.   Owner.add(this);
  117.   Owner.pack(); // Sort the Components in the Container.
  118.   detachedToolbar.removeAll();
  119.   detachedToolbar.dispose();  // Destroy the hovering window.
  120.   detachedToolbar = null; // this is so we can tell if the toolbar is docked.
  121.  }
  122.  
  123.  public boolean isDocked() // This method returns true if the toolbar is not hovering.
  124.  {
  125.   return (detachedToolbar == null);
  126.  }
  127.  
  128.  public void mouseClicked(MouseEvent e)
  129.  {
  130.   // This method must be implemented to support the MouseListener interface.
  131.  }
  132.  
  133.  /**
  134.   * This method is called in an event of a mouse drag.
  135.   * It can happen for 2 reasons:
  136.   * 1. The Toolbar is torn from place.
  137.   * 2. The Toolbar is being dragged, remember the Window class is not
  138.   * like the Frame class, it cannot be dragged by default.
  139.  **/
  140.  public void mouseDragged(MouseEvent e)
  141.  { // We use this method to detach the toolbar and to move it.
  142.   if (detachedToolbar == null) // If the toolbar is docked.
  143.    detachToolbar(); // Then it's being torn off, detach it.
  144.   else // If the toolbar is detached then we are trying to drag it.
  145.   {
  146.    // We comute the X and Y where to drag it too.
  147.    // This is not simple since the X and Y we are give is relative to the
  148.    // Component which is the window.
  149.    if(lastYLocationOnDrag == -1)
  150.    {
  151.     lastYLocationOnDrag = e.getY();
  152.     lastXLocationOnDrag = e.getX();
  153.    }
  154.    else
  155.    {
  156.     int x = detachedToolbar.getLocation().x + e.getX() - lastXLocationOnDrag,
  157.      y = detachedToolbar.getLocation().y + e.getY() - lastYLocationOnDrag;
  158.     lastYLocationOnDrag = -1;
  159.     lastXLocationOnDrag = -1;
  160.     detachedToolbar.setLocation(x,y);
  161.     repaint();
  162.    }
  163.   }
  164.  }
  165.  
  166.  public void mouseEntered(MouseEvent e)
  167.  {
  168.   // This method must be implemented to support the MouseMotionListener interface.
  169.  }
  170.  
  171.  public void mouseExited(MouseEvent e)
  172.  {
  173.   // This method must be implemented to support the MouseMotionListener interface.
  174.  }
  175.  
  176.  public void mouseMoved(MouseEvent e)
  177.  {
  178.   // This method must be implemented to support the MouseMotionListener interface.
  179.  }
  180.  
  181.  public void mousePressed(MouseEvent
  182. e)
  183.  {
  184.   // This method must be implemented to support the MouseListener interface.
  185.  }
  186.  
  187.  /**
  188.   * This method could mean the end of a drag operation. So here we use it to
  189.   * drop the Toolbar, if it's being dragged.
  190.  */
  191.  public void mouseReleased(MouseEvent e)
  192.  {
  193.   if(lastYLocationOnDrag != -1)
  194.   {
  195.    int x = detachedToolbar.getLocation().x + e.getX() - lastXLocationOnDrag,
  196.     y = detachedToolbar.getLocation().y + e.getY() - lastYLocationOnDrag;
  197.     lastYLocationOnDrag = -1;
  198.     lastXLocationOnDrag = -1;
  199.    detachedToolbar.setLocation(x,y);
  200.    repaint();
  201.   }
  202.  }
  203.  
  204.  /**
  205.   * This method sends the button pressed event to all listeners.
  206.   * It's needed so that an application can listen to the toolbar without
  207.   * maintaining logic for all the Buttons on it.
  208.  **/
  209.  private void sendEvent(int idOfTheButtonPressed)
  210.  {
  211.   ActionListener currentListener;
  212.   ActionEvent E = new
  213.       ActionEvent(listOfButtons.elementAt(idOfTheButtonPressed),
  214.       ActionEvent.ACTION_PERFORMED,
  215.       Integer.toString(idOfTheButtonPressed));
  216.   for (int counter = 0; counter < listOfActionListeners.size(); counter++)
  217.   {
  218.    currentListener = (ActionListener)listOfActionListeners.elementAt(counter);
  219.    currentListener.actionPerformed(E);
  220.   }
  221.  }
  222.  
  223.  /**
  224.   * This method is used by the detachToolbar method to handle the Window class.
  225.   * The reason this is in a seprate class is to abstaract the incompatible behavior
  226.   * among JDK versions.
  227.  **/
  228.  private void systemSpecificToolbarCalibration()
  229.  {
  230.   detachedToolbar.pack();
  231.   Dimension windowSize = detachedToolbar.getSize(),
  232.       buttonSize = ((Component)listOfButtons.elementAt(0)).getSize();
  233.   detachedToolbarTitleBar = new ToolbarTitleBar(windowSize.width,TOOLBAR_TITLEBAR_HEIGHT);
  234.  
  235.   detachedToolbar.add("North", detachedToolbarTitleBar);
  236.   detachedToolbar.pack();
  237.  }
  238.  
  239.  /**
  240.   * This method was originally used to send the button pressed events, but now
  241.   * I use it to check the button offset for a button ID.
  242.  **/
  243.  private int whichButtonGotPressed(Button B)
  244.  { // This method returns the Buttons offset in the vector.
  245.   for (int counter = 0; counter < listOfButtons.size() ; counter++)
  246.    if(listOfButtons.elementAt(counter) == B)
  247.     return(counter);
  248.   return(-1);
  249.  }
  250.  
  251.  private Window detachedToolbar = null; // This is the hovering Toolbar.
  252.  private ToolbarTitleBar detachedToolbarTitleBar; // This is the Tile bar of the Toolbar.
  253.  private Vector listOfTooltips = new Vector(); // This is a list of the Tooltip strings.
  254.  private Vector listOfActionListeners = new Vector(); // This is a list of the classes
  255.                                                       // that listen to toolbar events.
  256.  private Vector listOfButtons = new Vector(); // This is a list of the buttons.
  257.  private Frame Owner; // This is the Frame the Toolbar is located on.
  258.  private int lastXLocationOnDrag = -1;       // These two variables are used for
  259.                                              // dragging the toolbar.
  260.  private int lastYLocationOnDrag = -1;
  261.  private static final int TOOLBAR_TITLEBAR_HEIGHT = 5; // This is the height
  262.                                                        // of the toolbars title bar.
  263. }
  264.  
  265.  
  266.  
  267. /**
  268.  * This class is for internal use only. It paints the title on top of
  269.  * the detached window.
  270.  * The Window class is just a Canvas with no title to grab on to and this
  271.  * canvas makes it look similar.
  272. **/
  273. class ToolbarTitleBar extends Canvas
  274. {
  275.  ToolbarTitleBar(int width, int height)
  276.  {
  277.   super();
  278.   setSize(width,height); // Canvas on the window top in 3 pixel hight.
  279.   this.height = height;
  280.   this.width = width;
  281.  }
  282.  
  283.  public void paint(Graphics g)
  284.  {
  285.   g.setColor(SystemColor.activeCaption); // The SystemColor class contains
  286.                                          // colors specific to this system.
  287.   g.fillRect(0,0,width,i);
  288.  }
  289.  
  290.  private   int height;
  291.  private   int width;
  292. }
  293.