Image8.gif (38059 bytes)                              Java News Brief 
                    OCI                                                                     MAY ISSUE


Headlines:


NEW Java Workshops
Enterprise JavaBeans
Introduction to XML

OCI Education Center Open Enrollment

Students may now register for any of the open enrollment courses shown in the below schedule by calling 480-752-0042 or 1-888-9OCIOCI.  These OCI Education Center courses will be taught by OCI instructors at the Mesa Community College Business and Industry Institute.  Classes are held from 8:30 a.m. to 3:30 p.m.  Click hypertext for course descriptions.  For further information contact Ken Totten at the above numbers or mailto:training@ociweb.com

July
July 12-14   Object Oriented Analysis and Design (3 days)
July 13-16   CORBA Programming/Introduction to TAO (4 days)
July 15-16   Java Syntax for Non-C Programmers (2 days)
July 19-22   Java Programming (4 days)
July 26-29   Introduction to C++ for Non-C Programmers (4 days)
August
August 16-19   Object Oriented Programming and C++ (4 days)
August 16-17   Java Servlet Programming (2 days)
August 23-25   Developing GUIs using Java (3 days)
September
September 13-15   Introduction to XML (3 days)
September 21-24   CORBA Programming/Introduction to TAO (4 days)
September 20-22   Advanced Java Programming (3 days)
September 22-24   Advanced C++ (3 days)
September 27-28   JavaBeans Programming (2 days)
October
October 13-15   Enterprise JavaBeans
October 18-20   Object Oriented Analysis and Design (3 days)
October 21-22   Java Syntax for Non-C Programmers (2 days)
October 26-29   Introduction to C++ for Non-C Programmers (4 days)
November
November 2-5   Java Programming (4 days)
November 9-12 Object Oriented Programming and C++ (4 days)
December
December 7-10   CORBA Programming/Introduction to TAO (4 days)
December 8-10   Developing GUIs using Java (3 days)
December 16-17 Java Servlet Programming (2 days)



Object Computing, Inc. is a Sun Microsystems Authorized Java Center in St. Louis and a Member of the Object Management Group, OMG.  OCI specializes in distributed computing using Object Oriented and Web-enabled technologies and provides Consulting, Education and Product Development services to clients nation-wide.  For more information contact our Tempe office at  480-752-0042 or  mailto:info.



Java Technical Insight of the Month - Tooltips in AWT and Swing  
By Mark Volkmann, Principal Software Engineer, Object Computing, Inc.

Tooltips are small windows of text that popup when the user leaves the mouse cursor over a component for a second or two.  They are used to explain the functionality of the component.  Tooltips are an integral part of Swing components.  They can be specified by calling the setToolTipText method as shown below.

   
deleteButton.setToolTipText("Deletes the selected grocery item");

Tooltips are not supported in AWT.  However, the Window class can be used to add this capability.  The ToolTipManager class below does just that.  To use it, add code like this, calling setToolTipText for each component that is to have a tooltip.

  
  ToolTipManager.setToolTipText(deleteButton, "Deletes the selected grocery item");

The code below is heavily commented.  Feel free to use it as-is. 
--- start
package com.ociweb.awt;

import java.awt.*;
import java.awt.event.*;
import java.util.Hashtable;

/**
 * Provides tooltips for AWT Components.
 * @author R. Mark Volkmann, Object Computing, Inc.
 */
public class ToolTipManager implements MouseListener, Runnable {

   /**
    * The background color of the tooltips.
    */
   private static final Color BACKGROUND_COLOR = new Color(200, 200, 255);

   /**
    * The number of milliseconds that the mouse must remain
    * over a Component before its tooltip is displayed.
    */
   private static final int WAIT_TIME = 1000; // milliseconds

   /**
    * Only one ToolTipManager object per application is needed
    * so a singleton is created.
    */
   private static ToolTipManager singleton = new ToolTipManager();

   /**
    * The Component over which the mouse is currently positioned.
    */
   private Component currentComponent;

   /**
    * Mapping from Components to their tooltip text.
    */
   private Hashtable componentToTipTable = new Hashtable();

   /**
    * The Component used to display the tooltip.
    */
   private Label label = new Label();

   /**
    * A thread used to determine whether the cursor has remained
    * over a Component long enough to display its tooltip.
    */
   private Thread timerThread = new Thread(this);

   /**
    * The Window in which the tooltip is displayed.
    */
   private Window window;

   /**
    * Creates a ToolTipManager.
    * This is only invoked from this class since only a singleton is needed
.
    */
   private ToolTipManager() {
       label.setBackground(BACKGROUND_COLOR);
       timerThread.start();
   }

   /**
    * Creates the Window in which tooltips will be displayed.
    */
   private void createWindow() {
       // Find the Frame parent of currentComponent.
       Component top = currentComponent;
       while (true) {
           Container parent = top.getParent();
           if (parent == null) break;
           top = parent;
       }
       

       // Use that Frame for the parent of the tooltip Window.
       window = new Window((Frame) top);
     

        window.add(label, BorderLayout.CENTER);
   }

    /**
     * Prevents the tooltip from being displayed if the timer hasn't expired
     * and hides the tooltip window if it has.

     */
   private void hideTip() {
       // Prevent the tooltip from being displayed
       // if the timer hasn't expired.
       timerThread.interrupt();
       

       // Hide the tooltip Window if it is already displayed.
       if (window != null) {
           window.setVisible(false);
       }
   }

    /**
     * Adds a tooltip to a given Component.
     * @param component the Component
     * @param tip the tooltip String
     */
   public static void setToolTipText(Component component, String tip) {
       singleton.componentToTipTable.put(component, tip);       
       component.addMouseListener(singleton);
   }

    /**
     * Determines which Component the mouse cursor is over and
     * starts a thread to wait the appropriate amount of time
     * before displaying its tooltip.
     */
   public void mouseEntered(MouseEvent e) {
       currentComponent = (Component) e.getSource();
       

       // Notify the timerThread that the cursor is
       // now over a Component that has a tooltip.
       synchronized (this) {
           notify();
       }
   }

     /**
      * Interrupts the thread that is waiting to display the tooltip
      * and hides the tooltip window.
      */
   public void mouseExited(MouseEvent e) {
       if (e.getSource() == currentComponent) {
           hideTip();
       }
   }

     /**
      * Interrupts the thread that is waiting to display the tooltip
      * and hides the tooltip window.

       */
   public void mousePressed(MouseEvent e) {
       if (e.getSource() == currentComponent) {
           hideTip();
       }
   }

    // We don't need to do anything in these methods.
   public void mouseReleased(MouseEvent e) {}
   public void mouseClicked(MouseEvent e) {}

    /**
     * Removes a tooltip from a given Component.
     * @param component the Component
     */
   public static void removeToolTipText(Component component) {
       singleton.componentToTipTable.remove(component);       
       component.removeMouseListener(singleton);
   }

    /**
     * Implementation of the timer thread.
     * This waits the appropriate amount of time and then displays the tooltip.
     */
   public synchronized void run() {
       while (true) {
           try {
               // Wait until notified that the cursor is over a Component
               // that has a tooltip.
               synchronized (this) {
                   wait();
               }
               

               Thread.sleep(WAIT_TIME);
                   

               // Get the tooltip text to be displayed.
               String tip =
                   (String) componentToTipTable.get(currentComponent);
               label.setText(tip);
               

               if (window == null) {
                   createWindow();
               }
               window.pack();
   

                // Place the tooltip directly below its Component.
               Rectangle bounds = currentComponent.getBounds();
               Point location = currentComponent.getLocationOnScreen();
               window.setLocation(location.x, location.y + bounds.height);
               

                window.setVisible(true);
           } catch (InterruptedException e) {
               // Don't break out of loop!  Just wait for the mouse
               // to move over another component that has a tooltip.
           }
       }
   }
}
---end



The Java News Brief is a monthly newsletter.  The purpose and intent of this publication is to advance Java, provide technical value, and to announce available OCI Java services.  If you would prefer to not receive this newsletter or would like to subscribe please mailto:JNB and enter SUBSCRIBE or UNSUBSCRIBE within the Subject line.

Image9.gif (29736 bytes)
OMG.jpg (2965 bytes)

Copyright (c) 1999.  Object Computing, Inc.   All rights reserved.
Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries.  Object Computing, Inc. is independent of Sun Microsystems, Inc.


OMG, OBJECT MANAGEMENT GROUP, the OBJECT MANAGEMENT GROUP logo, CORBA, CORBA ACADEMY, THE INFORMATION BROKERAGE, DISTRIBUTED OBJECT COMPUTING, OBJECT REQUEST BROKER, ORB, OMG IDL, IIOP, The CORBA LOGO, CORBA THE GEEK & the CORBA THE GEEK design, UNIFIED MODELING LANGUAGE, and UML are trademarks of Object Management Group, Inc. in the United States.