// Frame mit Button der Tooltip besitzt public class ToolTipFrame extends Frame { private Button ok = new Button("Konsole"); public ToolTipFrame(String title) { super(title); this.setLayout(new FlowLayout()); // Die setToolTipText()-Methode von ToolTipManager bekommt die Komponente // sowie den anzuzeigenen Text übergeben. Anschließend wird auch bei // diesem Ok-Button ein Tooltip erscheinen, sobald die Maus // etwas länger über der Komponente liegt. ToolTipManager.setToolTipText(ok,"Tooltip-Text"); this.add(ok); } } // Manager Klasse package javacodebook.gui.tooltip; import java.awt.*; import java.awt.event.*; import java.util.Hashtable; /** * Diese Klasse einfach in den Klassenpfad übernehmen, und über * ToolTipManager.setToolTipText(komponente, "TooltipText hier eingeben") * den Tooltiptext setzen. */ public class ToolTipManager implements MouseListener, Runnable { /** * Hintergrundfarbe vom Tooltip */ private static final Color TOOLTIP_COLOR = new Color(200, 250,200); /** * Die Anzahl der Millisekunden, die gewartet werden soll bis der Tooltip * erscheint */ private static final int PAUSE_TIME = 1000; /** * Es soll pro Application nur ein ToolTipManger-Objekt geben, daher wird * dieser hier als Singleton realisiert. */ private static ToolTipManager singleton = new ToolTipManager(); /** * Die Komponente über der die Maus gerade positioniert ist. */ private Component currentComponent; /** * Zuordnung zwischen Tooltiptext und Komponente */ private Hashtable componentToTipMap = new Hashtable(); /** * Das Label zeigt den Tooltiptext an. */ private Label label = new Label(); /** * Dieser Thread stellt fest ob die Maus lange genug über der Komponente war. * Erst dann wird der Tooltiptext angzeigt. */ private Thread timerThread = new Thread(this); /** * Das Fenster in dem der Tooltip angezeigt wird */ private Window window; /** * Dieser Konstuktor wird bei der Initialisierung vom Attribut singleton * aufgerufen. Da er private ist wird gewährleistet, das es bei diesem einen * Aufruf pro Application bleibt. */ private ToolTipManager() { label.setBackground(TOOLTIP_COLOR); timerThread.start(); } /** * ToolTipFenster wird gebaut. */ private void createWindow() { // Das Frame in dem die currentComponent eingebettet ist wird gefunden. Component top = currentComponent; while (true) { Container parent = top.getParent(); if (parent == null) break; top = parent; } // Das Gefunde Frame wird "owner" vom Tooltip-Window. window = new Window((Frame) top); window.add(label, BorderLayout.CENTER); } /** * Lässt Tooltip verschwinden. Wird aufgerufen, wenn Komponente gedrückt, * oder Maus Komponente verlassen hat. */ private void hideTip() { // wird Komponente verlassen oder gedrückt bevor Tooltip angezeigt wurde, // verhindert dieser Interrupt die ungewünschte Darstellung des Tooltips. timerThread.interrupt(); // Falls Tooltip schon angezeigt, wird er hier unsichtbar gemacht if (window != null) { window.setVisible(false); } } /** * Fügt Tooltip mit angegebenem "toolTipText" einer bestehenden Komponente * "component" hinzu. */ public static void setToolTipText(Component component, String toolTipText) { singleton.componentToTipMap.put(component, toolTipText); component.addMouseListener(singleton); } /** * Komponente über der Maus gerade steht wird ermittelt, und Thread der * für die Darstellung der Komponente verantwortlich ist wird aufgeweckt. */ public void mouseEntered(MouseEvent e) { currentComponent = (Component) e.getSource(); // Man benötigt hierbei den Monitor auf das Objekt welches aufgeweckt // werden soll. Bekommt man durch synchronized synchronized (this) { notify(); } } /** * Wird aufgerufen wenn Maus Komponente verlässt, Tooltip wird unsichtbar * gemacht. */ public void mouseExited(MouseEvent e) { if (e.getSource() == currentComponent) { hideTip(); } } /** * Wird aufgerufen wenn Komponente geklickt wird, Tooltip wird unsichtbar * gemacht. */ public void mousePressed(MouseEvent e) { if (e.getSource() == currentComponent) { hideTip(); } } // Werden nicht benötigt, müssen aber überschrieben werden, da Sie im // MouseListener-Interface vorhanden sind public void mouseReleased(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} /** * Tooltip wird von übergebener Komponente weggenommen */ public static void removeToolTipText(Component component) { singleton.componentToTipMap.remove(component); component.removeMouseListener(singleton); } /** * Implementierung des Threads. Wartet die PAUSE_TIME ab, und wenn kein * interrupt aufgerufen wurde, wird Tooltip angezeigt. */ public synchronized void run() { while (true) { try { synchronized (this) { wait(); } Thread.sleep(PAUSE_TIME); // Tooltiptext wird ermittelt String tip = (String) componentToTipMap.get(currentComponent); label.setText(tip); // Fenster wird ggf. neu gebaut if (window == null) { createWindow(); } window.pack(); // Tooltip wird unter die Komponente gesetzt Rectangle bounds = currentComponent.getBounds(); Point location = currentComponent.getLocationOnScreen(); window.setLocation(location.x, location.y + bounds.height); window.setVisible(true); } catch (InterruptedException e) { // Thread wurde unterbrochen } } } }