SWT useful utilities : SWT Basics « SWT « Java Tutorial






/*
 * (c) Copyright 2004 by Heng Yuan
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
package cookxml.cookswt.util;

import java.util.HashMap;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

/**
 * SWT useful utilities.
 *
 * @since CookSwt 1.0
 * @author Heng Yuan
 */
public class SwtUtils
{
  /**
   * automatically dispose Color resource
   */
  public static boolean autoDisposeColor = true;
  /**
   * automatically dispose Font resource
   */
  public static boolean autoDisposeFont = true;
  /**
   * automatically dispose Image resource
   */
  public static boolean autoDisposeImage = true;
  /**
   * automatically dispose Image resource
   */
  public static boolean autoDisposeCursor = true;
  /**
   * This is a table of system colors that cannot be disposed.
   */
  private static HashMap s_systemColorTable;
  /**
   * This is a table of system cursors that cannot be disposed.
   */
  private static HashMap s_systemCursorTable;
  /**
   * This is a table of system images that cannot be disposed.
   */
  private static HashMap s_systemImageTable;

  /**
   * Setup the system color table for the given device.
   *
   * @param  device the display device.
   */
  private static void setupSystemColorTable (Device device)
  {
    HashMap colorTable = new HashMap ();
    for (int i = 0; i <= 35; ++i)
    {
      Color c = device.getSystemColor (i);
      colorTable.put (c, c);
    }
    s_systemColorTable = colorTable;
  }

  /**
   * Setup the system cursor table for the given device.
   *
   * @param  display the display device.
   */
  private static void setupSystemCursorTable (Display display)
  {
    HashMap cursorTable = new HashMap ();
    for (int i = 0; i <= 21; ++i)
    {
      Cursor c = display.getSystemCursor (i);
      cursorTable.put (c, c);
    }
    s_systemCursorTable = cursorTable;
  }

  /**
   * Setup the system cursor table for the given device.
   *
   * @param  display the display device.
   */
  private static void setupSystemImageTable (Display display)
  {
    HashMap imageTable = new HashMap ();
    Image image;
    image = display.getSystemImage (SWT.ICON_ERROR);
    imageTable.put (image, image);
    image = display.getSystemImage (SWT.ICON_INFORMATION);
    imageTable.put (image, image);
    image = display.getSystemImage (SWT.ICON_QUESTION);
    imageTable.put (image, image);
    image = display.getSystemImage (SWT.ICON_WARNING);
    imageTable.put (image, image);
    image = display.getSystemImage (SWT.ICON_WORKING);
    imageTable.put (image, image);
    s_systemImageTable = imageTable;
  }

  /**
   * Check if a color is a system color.  A system color cannot be disposed.
   *
   * @param  color The color to be disposed.
   * @param  device The device that contains the color.
   */
  public static boolean isSystemColor (Color color, Device device)
  {
    if (s_systemColorTable == null)
      setupSystemColorTable (device);
    return s_systemColorTable.get (color) == color;
  }

  /**
   * Check if a color is a system color.  A system color cannot be disposed.
   *
   * @param  cursor The cursor to be disposed.
   * @param  display The display device.
   */
  public static boolean isSystemCursor (Cursor cursor, Display display)
  {
    if (s_systemCursorTable == null)
      setupSystemCursorTable (display);
    return s_systemCursorTable.get (cursor) == cursor;
  }

  /**
   * Check if a color is a system color.  A system color cannot be disposed.
   *
   * @param  image The image to be disposed.
   * @param  display The display device.
   */
  public static boolean isSystemImage (Image image, Display display)
  {
    if (s_systemImageTable == null)
      setupSystemImageTable (display);
    return s_systemImageTable.get (image) == image;
  }

  /**
   * Check if a color is a system color.  A system color cannot be disposed.
   *
   * @param  font The font to be disposed.
   * @param  device The display device.
   */
  public static boolean isSystemFont (Font font, Device device)
  {
    return device.getSystemFont () == font;
  }

  /**
   * Dispose a color if it is not a system color.
   *
   * @param  color The color to be disposed.
   * @param  device The device that contains the color.
   */
  public static void disposeColor (Color color, Device device)
  {
    if (color.isDisposed ())
      return;
    if (!isSystemColor (color, device))
    {
      assert disposeDebug ("Dispose color: " + color);
      color.dispose ();
    }
  }

  /**
   * Dispose a color if it is not a system color.
   *
   * @param  image The image to be disposed.
   * @param  device The device that contains the color.
   */
  public static void disposeImage (Image image, Display device)
  {
    if (image.isDisposed ())
      return;
    if (!isSystemImage (image, device))
    {
      assert disposeDebug ("Dispose image: " + image);
      image.dispose ();
    }
  }

  /**
   * Attach a DisposeListener that dispose the resource when the widget
   * object is disposed.
   *
   * @param  widget the widget to listen to.
   * @param  color the resource to be disposed.
   */
  public static void attachColorDisposeListener (Widget widget, Color color)
  {
    if (autoDisposeColor &&
      !isSystemColor (color, widget.getDisplay ()))
      widget.addDisposeListener (new ColorDisposeListener (color));
  }

  /**
   * Attach a DisposeListener that dispose the resource when the widget
   * object is disposed.
   *
   * @param  widget the widget to listen to.
   * @param  cursor the resource to be disposed.
   */
  public static void attachCursorDisposeListener (Widget widget, Cursor cursor)
  {
    if (autoDisposeCursor &&
      !isSystemCursor (cursor, widget.getDisplay ()))
      widget.addDisposeListener (new CursorDisposeListener (cursor));
  }

  /**
   * Attach a DisposeListener that dispose the resource when the widget
   * object is disposed.
   *
   * @param  widget the widget to listen to.
   * @param  font the resource to be disposed.
   */
  public static void attachFontDisposeListener (Widget widget, Font font)
  {
    if (autoDisposeFont &&
      !isSystemFont (font, widget.getDisplay ()))
      widget.addDisposeListener (new FontDisposeListener (font));
  }

  /**
   * Attach a DisposeListener that dispose the resource when the widget
   * object is disposed.
   *
   * @param  widget the widget to listen to.
   * @param  image the resource to be disposed.
   */
  public static void attachImageDisposeListener (Widget widget, Image image)
  {
    if (autoDisposeImage &&
       !isSystemImage (image, widget.getDisplay ()))
      widget.addDisposeListener (new ImageDisposeListener (image));
  }

  /**
   * Attach a dropdown menu to a drop down ToolItem.  The drop down menu will be
   * automatically positioned and displayed at under the ToolItem.
   *
   * @param  item the drop down tool item
   * @param  menu the drop down menu
   */
  public static void attachToolItemDropDownMenu (ToolItem item, Menu menu)
  {
    item.addSelectionListener (new DropDownListener (menu));
  }

  /**
   * Open all the shells inside the Display object and dispose the Display
   * after all shells are disposed.
   *
   * @param display the Display object.
   */
  public static void showDisplay (Display display)
  {
    // open shells for display
    Shell[] shells = display.getShells ();
    for (int i = 0; i < shells.length; ++i)
    {
      if (!shells[i].isDisposed () && !shells[i].isVisible ())
        shells[i].open ();
    }

    // exit after all shells are disposed
    while (!display.isDisposed ())
    {
      shells = display.getShells ();
      boolean canExit = true;
      for (int i = 0; i < shells.length; ++i)
      {
        if (!shells[i].isDisposed ())
        {
          canExit = false;
          break;
        }
      }
      if (canExit)
        break;
      if (!display.readAndDispatch ())
        display.sleep ();
    }
    if (!display.isDisposed ())
      display.dispose ();
  }

  /**
   * This function is supposed to work in conjunction with assert to generate
   * a debug message but does not really throw an Exception
   *
   * @param  msg the message to be printed.
   * @return  true
   */
  public static boolean disposeDebug (String msg)
  {
    System.out.println (msg);
    return true;
  }
}








17.1.SWT Basics
17.1.1.Two simple rules to guide your disposal efforts
17.1.2.Operating System Resources
17.1.3.The SWT Class-Constants and Methods
17.1.4.Coding Your First SWT Program: Hello WorldCoding Your First SWT Program: Hello World
17.1.5.SWT useful utilities