/******************************************************************************* * Copyright (c) 2000, 2012 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.swt.examples.hoverhelp; import java.io.*; import java.text.*; import java.util.*; import org.eclipse.swt.*; import org.eclipse.swt.events.*; import org.eclipse.swt.graphics.*; import org.eclipse.swt.layout.*; import org.eclipse.swt.widgets.*; /** * This example demonstrates how to implement hover help feedback * using the MouseTrackListener. */ public class HoverHelp { private static ResourceBundle resourceBundle = ResourceBundle.getBundle("examples_hoverhelp"); static final int hhiInformation = 0, hhiWarning = 1; static final String[] imageLocations = { "information.gif", "warning.gif" }; Image images[]; /** * Runs main program. */ public static void main (String [] args) { Display display = new Display(); Shell shell = new HoverHelp().open(display); // Event loop while (shell != null && ! shell.isDisposed()) { if (! display.readAndDispatch()) display.sleep(); } // Cleanup display.dispose(); } /** * Opens the main program. */ public Shell open(Display display) { // Load the images Class clazz = HoverHelp.class; try { if (images == null) { images = new Image[imageLocations.length]; for (int i = 0; i < imageLocations.length; ++i) { InputStream stream = clazz.getResourceAsStream(imageLocations[i]); ImageData source = new ImageData(stream); ImageData mask = source.getTransparencyMask(); images[i] = new Image(display, source, mask); try { stream.close(); } catch (IOException e) { e.printStackTrace(); } } } } catch (Exception ex) { System.err.println(getResourceString("error.CouldNotLoadResources", new Object[] { ex.getMessage() })); return null; } // Create the window Shell shell = new Shell(); createPartControl(shell); shell.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { /* Free resources */ if (images != null) { for (int i = 0; i < images.length; i++) { final Image image = images[i]; if (image != null) image.dispose(); } images = null; } } }); shell.pack(); shell.open(); return shell; } /** * Gets a string from the resource bundle. * We don't want to crash because of a missing String. * Returns the key if not found. */ public String getResourceString(String key) { try { return resourceBundle.getString(key); } catch (MissingResourceException e) { return key; } catch (NullPointerException e) { return "!" + key + "!"; } } /** * Gets a string from the resource bundle and binds it * with the given arguments. If the key is not found, * return the key. */ public String getResourceString(String key, Object[] args) { try { return MessageFormat.format(getResourceString(key), args); } catch (MissingResourceException e) { return key; } catch (NullPointerException e) { return "!" + key + "!"; } } /** * Creates the example */ public void createPartControl(Composite frame) { final ToolTipHandler tooltip = new ToolTipHandler(frame.getShell()); GridLayout layout = new GridLayout(); layout.numColumns = 3; frame.setLayout(layout); ToolBar bar = new ToolBar (frame, SWT.BORDER); for (int i=0; i<5; i++) { ToolItem item = new ToolItem (bar, SWT.PUSH); item.setText (getResourceString("ToolItem.text", new Object[] { new Integer(i) })); item.setData ("TIP_TEXT", getResourceString("ToolItem.tooltip", new Object[] { item.getText() })); item.setData ("TIP_HELPTEXTHANDLER", new ToolTipHelpTextHandler() { public String getHelpText(Widget widget) { Item item = (Item) widget; return getResourceString("ToolItem.help", new Object[] { item.getText() }); } }); } GridData gridData = new GridData(); gridData.horizontalSpan = 3; bar.setLayoutData(gridData); tooltip.activateHoverHelp(bar); Table table = new Table (frame, SWT.BORDER); for (int i=0; i<4; i++) { TableItem item = new TableItem (table, SWT.PUSH); item.setText (getResourceString("Item", new Object[] { new Integer(i) })); item.setData ("TIP_IMAGE", images[hhiInformation]); item.setText (getResourceString("TableItem.text", new Object[] { new Integer(i) })); item.setData ("TIP_TEXT", getResourceString("TableItem.tooltip", new Object[] { item.getText() })); item.setData ("TIP_HELPTEXTHANDLER", new ToolTipHelpTextHandler() { public String getHelpText(Widget widget) { Item item = (Item) widget; return getResourceString("TableItem.help", new Object[] { item.getText() }); } }); } table.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL)); tooltip.activateHoverHelp(table); Tree tree = new Tree (frame, SWT.BORDER); for (int i=0; i<4; i++) { TreeItem item = new TreeItem (tree, SWT.PUSH); item.setText (getResourceString("Item", new Object[] { new Integer(i) })); item.setData ("TIP_IMAGE", images[hhiWarning]); item.setText (getResourceString("TreeItem.text", new Object[] { new Integer(i) })); item.setData ("TIP_TEXT", getResourceString("TreeItem.tooltip", new Object[] { item.getText() })); item.setData ("TIP_HELPTEXTHANDLER", new ToolTipHelpTextHandler() { public String getHelpText(Widget widget) { Item item = (Item) widget; return getResourceString("TreeItem.help", new Object[] { item.getText() }); } }); } tree.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL)); tooltip.activateHoverHelp(tree); Button button = new Button (frame, SWT.PUSH); button.setText (getResourceString("Hello.text")); button.setData ("TIP_TEXT", getResourceString("Hello.tooltip")); tooltip.activateHoverHelp(button); } /** * Emulated tooltip handler * Notice that we could display anything in a tooltip besides text and images. * For instance, it might make sense to embed large tables of data or buttons linking * data under inspection to material elsewhere, or perform dynamic lookup for creating * tooltip text on the fly. */ protected static class ToolTipHandler { private Shell parentShell; private Shell tipShell; private Label tipLabelImage, tipLabelText; private Widget tipWidget; // widget this tooltip is hovering over private Point tipPosition; // the position being hovered over /** * Creates a new tooltip handler * * @param parent the parent Shell */ public ToolTipHandler(Shell parent) { final Display display = parent.getDisplay(); this.parentShell = parent; tipShell = new Shell(parent, SWT.ON_TOP | SWT.TOOL); GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 2; gridLayout.marginWidth = 2; gridLayout.marginHeight = 2; tipShell.setLayout(gridLayout); tipShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); tipLabelImage = new Label(tipShell, SWT.NONE); tipLabelImage.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND)); tipLabelImage.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); tipLabelImage.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER)); tipLabelText = new Label(tipShell, SWT.NONE); tipLabelText.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND)); tipLabelText.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); tipLabelText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER)); } /** * Enables customized hover help for a specified control * * @control the control on which to enable hoverhelp */ public void activateHoverHelp(final Control control) { /* * Get out of the way if we attempt to activate the control underneath the tooltip */ control.addMouseListener(new MouseAdapter () { public void mouseDown (MouseEvent e) { if (tipShell.isVisible()) tipShell.setVisible(false); } }); /* * Trap hover events to pop-up tooltip */ control.addMouseTrackListener(new MouseTrackAdapter () { public void mouseExit(MouseEvent e) { if (tipShell.isVisible()) tipShell.setVisible(false); tipWidget = null; } public void mouseHover (MouseEvent event) { Point pt = new Point (event.x, event.y); Widget widget = event.widget; if (widget instanceof ToolBar) { ToolBar w = (ToolBar) widget; widget = w.getItem (pt); } if (widget instanceof Table) { Table w = (Table) widget; widget = w.getItem (pt); } if (widget instanceof Tree) { Tree w = (Tree) widget; widget = w.getItem (pt); } if (widget == null) { tipShell.setVisible(false); tipWidget = null; return; } if (widget == tipWidget) return; tipWidget = widget; tipPosition = control.toDisplay(pt); String text = (String) widget.getData("TIP_TEXT"); Image image = (Image) widget.getData("TIP_IMAGE"); tipLabelText.setText(text != null ? text : ""); tipLabelImage.setImage(image); // accepts null tipShell.pack(); setHoverLocation(tipShell, tipPosition); tipShell.setVisible(true); } }); /* * Trap F1 Help to pop up a custom help box */ control.addHelpListener(new HelpListener () { public void helpRequested(HelpEvent event) { if (tipWidget == null) return; ToolTipHelpTextHandler handler = (ToolTipHelpTextHandler) tipWidget.getData("TIP_HELPTEXTHANDLER"); if (handler == null) return; String text = handler.getHelpText(tipWidget); if (text == null) return; if (tipShell.isVisible()) { tipShell.setVisible(false); Shell helpShell = new Shell(parentShell, SWT.SHELL_TRIM); helpShell.setLayout(new FillLayout()); Label label = new Label(helpShell, SWT.NONE); label.setText(text); helpShell.pack(); setHoverLocation(helpShell, tipPosition); helpShell.open(); } } }); } /** * Sets the location for a hovering shell * @param shell the object that is to hover * @param position the position of a widget to hover over * @return the top-left location for a hovering box */ private void setHoverLocation(Shell shell, Point position) { Rectangle displayBounds = shell.getDisplay().getBounds(); Rectangle shellBounds = shell.getBounds(); shellBounds.x = Math.max(Math.min(position.x, displayBounds.width - shellBounds.width), 0); shellBounds.y = Math.max(Math.min(position.y + 16, displayBounds.height - shellBounds.height), 0); shell.setBounds(shellBounds); } } /** * ToolTip help handler */ protected interface ToolTipHelpTextHandler { /** * Get help text * @param widget the widget that is under help * @return a help text string */ public String getHelpText(Widget widget); } }