Package org.eclipse.jface.window

Source Code of org.eclipse.jface.window.Window$DefaultExceptionHandler

/*******************************************************************************
* Copyright (c) 2000, 2008 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.jface.window;

import java.util.ArrayList;

import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.core.runtime.Assert;
import org.eclipse.jface.util.Geometry;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Layout;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;

/**
* A JFace window is an object that has no visual representation (no widgets)
* until it is told to open.
* <p>
* Creating a window involves the following steps:
* <ul>
* <li>creating an instance of a concrete subclass of <code>Window</code>
* </li>
* <li>creating the window's shell and widget tree by calling
* <code>create</code> (optional)</li>
* <li>assigning the window to a window manager using
* <code>WindowManager.add</code> (optional)</li>
* <li>opening the window by calling <code>open</code></li>
* </ul>
* Opening the window will create its shell and widget tree if they have not
* already been created. When the window is closed, the shell and widget tree
* are disposed of and are no longer referenced, and the window is automatically
* removed from its window manager. A window may be reopened.
* </p>
* <p>
* The JFace window framework (this package) consists of this class,
* <code>Window</code>, the abstract base of all windows, and one concrete
* window classes (<code>ApplicationWindow</code>) which may also be
* subclassed. Clients may define additional window subclasses as required.
* </p>
* <p>
* The <code>Window</code> class provides methods that subclasses may
* override to configure the window, including:
* <ul>
* <li><code>close</code>- extend to free other SWT resources</li>
* <li><code>configureShell</code>- extend or reimplement to set shell
* properties before window opens</li>
* <li><code>createContents</code>- extend or reimplement to create controls
* before window opens</li>
* <li><code>getInitialSize</code>- reimplement to give the initial size for
* the shell</li>
* <li><code>getInitialLocation</code>- reimplement to give the initial
* location for the shell</li>
* <li><code>getShellListener</code>- extend or reimplement to receive shell
* events</li>
* <li><code>handleFontChange</code>- reimplement to respond to font changes
* </li>
* <li><code>handleShellCloseEvent</code>- extend or reimplement to handle
* shell closings</li>
* </ul>
* </p>
*/
public abstract class Window implements IShellProvider {

  /**
   * Standard return code constant (value 0) indicating that the window was
   * opened.
   *
   * @see #open
   */
  public static final int OK = 0;

  /**
   * Standard return code constant (value 1) indicating that the window was
   * canceled.
   *
   * @see #open
   */
  public static final int CANCEL = 1;

  /**
   * An array of images to be used for the window. It is expected that the
   * array will contain the same icon rendered at different resolutions.
   */
  private static Image[] defaultImages;

  /**
   * This interface defines a Exception Handler which can be set as a global
   * handler and will be called if an exception happens in the event loop.
   */
  public static interface IExceptionHandler {
    /**
     * Handle the exception.
     *
     * @param t
     *            The exception that occured.
     */
    public void handleException(Throwable t);
  }

  /**
   * Defines a default exception handler.
   */
  private static class DefaultExceptionHandler implements IExceptionHandler {
    /*
     * (non-Javadoc)
     *
     * @see org.eclipse.jface.window.Window.IExceptionHandler#handleException(java.lang.Throwable)
     */
    public void handleException(Throwable t) {
      if (t instanceof ThreadDeath) {
        // Don't catch ThreadDeath as this is a normal occurrence when
        // the thread dies
        throw (ThreadDeath) t;
      }
      // Try to keep running.
      t.printStackTrace();
    }
  }

  /**
   * The exception handler for this application.
   */
  private static IExceptionHandler exceptionHandler = new DefaultExceptionHandler();
 
  /**
   * The default orientation of the window. By default
   * it is SWT#NONE but it can also be SWT#LEFT_TO_RIGHT
   * or SWT#RIGHT_TO_LEFT
   */
  private static int orientation = SWT.NONE;

    /**
     * Object used to locate the default parent for modal shells
     */
    private static IShellProvider defaultModalParent = new IShellProvider() {
        public Shell getShell() {
            Display d = Display.getCurrent();
           
            if (d == null) {
                return null;
            }

            Shell parent = d.getActiveShell();
           
            // Make sure we don't pick a parent that has a modal child (this can lock the app)
            if (parent == null) {
                // If this is a top-level window, then there must not be any open modal windows.
                parent = getModalChild(Display.getCurrent().getShells());
            } else {
                // If we picked a parent with a modal child, use the modal child instead
                Shell modalChild = getModalChild(parent.getShells());
                if (modalChild != null) {
                    parent = modalChild;
                }
            }
           
            return parent;
        }
    };
   
  /**
   * Object that returns the parent shell.
   */
  private IShellProvider parentShell;

  /**
   * Shell style bits.
   *
   * @see #setShellStyle
   */
  private int shellStyle = SWT.SHELL_TRIM;

  /**
   * Window manager, or <code>null</code> if none.
   *
   * @see #setWindowManager
   */
  private WindowManager windowManager;

  /**
   * Window shell, or <code>null</code> if none.
   */
  private Shell shell;

  /**
   * Top level SWT control, or <code>null</code> if none
   */
  private Control contents;

  /**
   * Window return code; initially <code>OK</code>.
   *
   * @see #setReturnCode
   */
  private int returnCode = OK;

  /**
   * <code>true</code> if the <code>open</code> method should not return
   * until the window closes, and <code>false</code> if the
   * <code>open</code> method should return immediately; initially
   * <code>false</code> (non-blocking).
   *
   * @see #setBlockOnOpen
   */
  private boolean block = false;

  /**
   * Internal class for informing this window when fonts change.
   */
  private class FontChangeListener implements IPropertyChangeListener {
    public void propertyChange(PropertyChangeEvent event) {
      handleFontChange(event);
    }
  }

  /**
   * Internal font change listener.
   */
  private FontChangeListener fontChangeListener;

  /**
   * Internal fields to detect if shell size has been set
   */
  private boolean resizeHasOccurred = false;

  private Listener resizeListener;
  /**
   * Creates a window instance, whose shell will be created under the given
   * parent shell. Note that the window will have no visual representation
   * until it is told to open. By default, <code>open</code> does not block.
   *
   * @param parentShell
   *            the parent shell, or <code>null</code> to create a top-level
   *            shell. Try passing "(Shell)null" to this method instead of "null"
     *            if your compiler complains about an ambiguity error.
   * @see #setBlockOnOpen
   * @see #getDefaultOrientation()
   */
  protected Window(Shell parentShell) {
        this(new SameShellProvider(parentShell));
       
        if(parentShell == null) {
      setShellStyle(getShellStyle() | getDefaultOrientation());
    }
  }
   
    /**
     * Creates a new window which will create its shell as a child of whatever
     * the given shellProvider returns.
     *
     * @param shellProvider object that will return the current parent shell. Not null.
     *
     * @since 3.1
     */
    protected Window(IShellProvider shellProvider) {
        Assert.isNotNull(shellProvider);
        this.parentShell = shellProvider;  
    }

  /**
   * Determines if the window should handle the close event or do nothing.
   * <p>
   * The default implementation of this framework method returns
   * <code>true</code>, which will allow the
   * <code>handleShellCloseEvent</code> method to be called. Subclasses may
   * extend or reimplement.
   * </p>
   *
   * @return whether the window should handle the close event.
   */
  protected boolean canHandleShellCloseEvent() {
    return true;
  }

  /**
   * Closes this window, disposes its shell, and removes this window from its
   * window manager (if it has one).
   * <p>
   * This framework method may be extended (<code>super.close</code> must
   * be called).
   * </p>
   * <p>
   *  Note that in order to prevent recursive calls to this method
   *  it does not call <code>Shell#close()</code>. As a result <code>ShellListener</code>s
   *  will not receive a <code>shellClosed</code> event.
   *  </p>
   *
   * @return <code>true</code> if the window is (or was already) closed, and
   *         <code>false</code> if it is still open
   */
  public boolean close() {
   
    // stop listening for font changes
    if (fontChangeListener != null) {
      JFaceResources.getFontRegistry().removeListener(fontChangeListener);
      fontChangeListener = null;
    }
   
    // remove this window from a window manager if it has one
    if (windowManager != null) {
      windowManager.remove(this);
      windowManager = null;
    }

    if (shell == null || shell.isDisposed()) {
      return true;
    }

    // If we "close" the shell recursion will occur.
    // Instead, we need to "dispose" the shell to remove it from the
    // display.
    shell.dispose();
    shell = null;
    contents = null;

    return true;
  }

  /**
   * Configures the given shell in preparation for opening this window in it.
   * <p>
   * The default implementation of this framework method sets the shell's
   * image and gives it a grid layout. Subclasses may extend or reimplement.
   * </p>
   *
   * @param newShell
   *            the shell
   */
  protected void configureShell(Shell newShell) {

    // The single image version of this code had a comment related to bug
    // 46624,
    // and some code that did nothing if the stored image was already
    // disposed.
    // The equivalent in the multi-image version seems to be to remove the
    // disposed images from the array passed to the shell.
    if (defaultImages != null && defaultImages.length > 0) {
      ArrayList nonDisposedImages = new ArrayList(defaultImages.length);
      for (int i = 0; i < defaultImages.length; ++i) {
        if (defaultImages[i] != null && !defaultImages[i].isDisposed()) {
          nonDisposedImages.add(defaultImages[i]);
        }
      }

      if (nonDisposedImages.size() <= 0) {
        System.err.println("Window.configureShell: images disposed"); //$NON-NLS-1$
      } else {
        Image[] array = new Image[nonDisposedImages.size()];
        nonDisposedImages.toArray(array);
        newShell.setImages(array);
      }
    }

    Layout layout = getLayout();
    if (layout != null) {
      newShell.setLayout(layout);
    }
  }

  /**
   * Creates the layout for the shell. The layout created here will be
   * attached to the composite passed into createContents. The default
   * implementation returns a GridLayout with no margins. Subclasses that
   * change the layout type by overriding this method should also override
   * createContents.
   *
   * <p>
   * A return value of null indicates that no layout should be attached to the
   * composite. In this case, the layout may be attached within
   * createContents.
   * </p>
   *
   * @return a newly created Layout or null if no layout should be attached.
   * @since 3.0
   */
  protected Layout getLayout() {
    GridLayout layout = new GridLayout();
    layout.marginHeight = 0;
    layout.marginWidth = 0;
    return layout;
  }

  /**
   * Constrain the shell size to be no larger than the display bounds.
   *
   * @since 2.0
   */
  protected void constrainShellSize() {
    // limit the shell size to the display size
    Rectangle bounds = shell.getBounds();
    Rectangle constrained = getConstrainedShellBounds(bounds);
    if (!bounds.equals(constrained)) {
      shell.setBounds(constrained);
    }
  }

  /**
   * Creates this window's widgetry in a new top-level shell.
   * <p>
   * The default implementation of this framework method creates this window's
   * shell (by calling <code>createShell</code>), and its controls (by
   * calling <code>createContents</code>), then initializes this window's
   * shell bounds (by calling <code>initializeBounds</code>).
   * </p>
   */
  public void create() {
    shell = createShell();
    contents = createContents(shell);

    //initialize the bounds of the shell to that appropriate for the
    // contents
    initializeBounds();
  }

  /**
   * Creates and returns this window's contents. Subclasses may attach any
   * number of children to the parent. As a convenience, the return value of
   * this method will be remembered and returned by subsequent calls to
   * getContents(). Subclasses may modify the parent's layout if they overload
   * getLayout() to return null.
   *
   * <p>
   * It is common practise to create and return a single composite that
   * contains the entire window contents.
   * </p>
   *
   * <p>
   * The default implementation of this framework method creates an instance
   * of <code>Composite</code>. Subclasses may override.
   * </p>
   *
   * @param parent
   *            the parent composite for the controls in this window. The type
   *            of layout used is determined by getLayout()
   *
   * @return the control that will be returned by subsequent calls to
   *         getContents()
   */
  protected Control createContents(Composite parent) {
    // by default, just create a composite
    return new Composite(parent, SWT.NONE);
  }

  /**
   * Creates and returns this window's shell.
   * <p>
   * This method creates a new shell and configures
   * it using <code>configureShell</code>. Subclasses
   * should  override <code>configureShell</code> if the
   * shell needs to be customized.
   * </p>
   *
   * @return the shell
   */
  protected final Shell createShell() {

    Shell newParent = getParentShell();
    if(newParent != null &&  newParent.isDisposed()){
      parentShell = new SameShellProvider(null);
      newParent = getParentShell();//Find a better parent
    }
   
    //Create the shell
    Shell newShell = new Shell(newParent, getShellStyle());

    resizeListener = new Listener() {
      public void handleEvent(Event e) {
        resizeHasOccurred = true;
      }
    };

    newShell.addListener(SWT.Resize, resizeListener);
    newShell.setData(this);

    //Add a listener
    newShell.addShellListener(getShellListener());

    //Set the layout
    configureShell(newShell);

    //Register for font changes
    if (fontChangeListener == null) {
      fontChangeListener = new FontChangeListener();
    }
    JFaceResources.getFontRegistry().addListener(fontChangeListener);

    return newShell;
  }

  /**
   * Returns the top level control for this window. The parent of this control
   * is the shell.
   *
   * @return the top level control, or <code>null</code> if this window's
   *         control has not been created yet
   */
  protected Control getContents() {
    return contents;
  }

  /**
   * Returns the default image. This is the image that will be used for
   * windows that have no shell image at the time they are opened. There is no
   * default image unless one is installed via <code>setDefaultImage</code>.
   *
   * @return the default image, or <code>null</code> if none
   * @see #setDefaultImage
   */
  public static Image getDefaultImage() {
    return (defaultImages == null || defaultImages.length < 1) ? null
        : defaultImages[0];
  }

  /**
   * Returns the array of default images to use for newly opened windows. It
   * is expected that the array will contain the same icon rendered at
   * different resolutions.
   *
   * @see org.eclipse.swt.widgets.Decorations#setImages(org.eclipse.swt.graphics.Image[])
   *
   * @return the array of images to be used when a new window is opened
   * @see #setDefaultImages
   * @since 3.0
   */
  public static Image[] getDefaultImages() {
    return (defaultImages == null ? new Image[0] : defaultImages);
  }

  /**
   * Returns the initial location to use for the shell. The default
   * implementation centers the shell horizontally (1/2 of the difference to
   * the left and 1/2 to the right) and vertically (1/3 above and 2/3 below)
   * relative to the parent shell, or display bounds if there is no parent
   * shell.
   *
   * @param initialSize
   *            the initial size of the shell, as returned by
   *            <code>getInitialSize</code>.
   * @return the initial location of the shell
   */
  protected Point getInitialLocation(Point initialSize) {
    Composite parent = shell.getParent();

    Monitor monitor = shell.getDisplay().getPrimaryMonitor();
    if (parent != null) {
      monitor = parent.getMonitor();
    }

    Rectangle monitorBounds = monitor.getClientArea();
    Point centerPoint;
    if (parent != null) {
      centerPoint = Geometry.centerPoint(parent.getBounds());
    } else {
      centerPoint = Geometry.centerPoint(monitorBounds);
    }

    return new Point(centerPoint.x - (initialSize.x / 2), Math.max(
        monitorBounds.y, Math.min(centerPoint.y
            - (initialSize.y * 2 / 3), monitorBounds.y
            + monitorBounds.height - initialSize.y)));
  }

  /**
   * Returns the initial size to use for the shell. The default implementation
   * returns the preferred size of the shell, using
   * <code>Shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true)</code>.
   *
   * @return the initial size of the shell
   */
  protected Point getInitialSize() {
    return shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
  }

    /**
     * Returns the most specific modal child from the given list of Shells.
     *
     * @param toSearch shells to search for modal children
     * @return the most specific modal child, or null if none
     *
     * @since 3.1
     */
    private static Shell getModalChild(Shell[] toSearch) {
        int modal = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL | SWT.PRIMARY_MODAL;
       
        for (int i = toSearch.length - 1; i >= 0; i--) {
            Shell shell = toSearch[i];
           
            // Check if this shell has a modal child
            Shell[] children = shell.getShells();
            Shell modalChild = getModalChild(children);
            if (modalChild != null) {
                return modalChild;
            }
           
            // If not, check if this shell is modal itself
            if (shell.isVisible() && (shell.getStyle() & modal) != 0) {
                return shell;
            }
        }
       
        return null;
    }
   
  /**
   * Returns parent shell, under which this window's shell is created.
   *
   * @return the parent shell, or <code>null</code> if there is no parent
   *         shell
   */
  protected Shell getParentShell() {
        Shell parent = parentShell.getShell();
       
        int modal = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL | SWT.PRIMARY_MODAL;
       
        if ((getShellStyle() & modal) != 0) {
            // If this is a modal shell with no parent, pick a shell using defaultModalParent.
            if (parent == null) {
                parent = defaultModalParent.getShell();
            }
        }
       
        return parent;
  }

  /**
   * Returns this window's return code. A window's return codes are
   * window-specific, although two standard return codes are predefined:
   * <code>OK</code> and <code>CANCEL</code>.
   *
   * @return the return code
   */
  public int getReturnCode() {
    return returnCode;
  }

  /**
   * Returns this window's shell.
   *
   * @return this window's shell, or <code>null</code> if this window's
   *         shell has not been created yet
   */
  public Shell getShell() {
    return shell;
  }

  /**
   * Returns a shell listener. This shell listener gets registered with this
   * window's shell.
   * <p>
   * The default implementation of this framework method returns a new
   * listener that makes this window the active window for its window manager
   * (if it has one) when the shell is activated, and calls the framework
   * method <code>handleShellCloseEvent</code> when the shell is closed.
   * Subclasses may extend or reimplement.
   * </p>
   *
   * @return a shell listener
   */
  protected ShellListener getShellListener() {
    return new ShellAdapter() {
      public void shellClosed(ShellEvent event) {
        event.doit = false; // don't close now
        if (canHandleShellCloseEvent()) {
          handleShellCloseEvent();
        }
      }
    };
  }

  /**
   * Returns the shell style bits.
   * <p>
   * The default value is <code>SWT.CLOSE|SWT.MIN|SWT.MAX|SWT.RESIZE</code>.
   * Subclassers should call <code>setShellStyle</code> to change this
   * value, rather than overriding this method.
   * </p>
   *
   * @return the shell style bits
   */
  protected int getShellStyle() {
    return shellStyle;
  }

  /**
   * Returns the window manager of this window.
   *
   * @return the WindowManager, or <code>null</code> if none
   */
  public WindowManager getWindowManager() {
    return windowManager;
  }

  /**
   * Notifies of a font property change.
   * <p>
   * The default implementation of this framework method does nothing.
   * Subclasses may reimplement.
   * </p>
   *
   * @param event
   *            the property change event detailing what changed
   */
  protected void handleFontChange(PropertyChangeEvent event) {
    // do nothing
  }

  /**
   * Notifies that the window's close button was pressed, the close menu was
   * selected, or the ESCAPE key pressed.
   * <p>
   * The default implementation of this framework method sets the window's
   * return code to <code>CANCEL</code> and closes the window using
   * <code>close</code>. Subclasses may extend or reimplement.
   * </p>
   */
  protected void handleShellCloseEvent() {
    setReturnCode(CANCEL);
    close();
  }

  /**
   * Initializes the location and size of this window's SWT shell after it has
   * been created.
   * <p>
   * This framework method is called by the <code>create</code> framework
   * method. The default implementation calls <code>getInitialSize</code>
   * and <code>getInitialLocation</code> and passes the results to
   * <code>Shell.setBounds</code>. This is only done if the bounds of the
   * shell have not already been modified. Subclasses may extend or
   * reimplement.
   * </p>
   */
  protected void initializeBounds() {
    if (resizeListener != null) {
      shell.removeListener(SWT.Resize, resizeListener);
    }
    if (resizeHasOccurred) { // Check if shell size has been set already.
      return;
    }

    Point size = getInitialSize();
    Point location = getInitialLocation(size);
    shell.setBounds(getConstrainedShellBounds(new Rectangle(location.x,
        location.y, size.x, size.y)));
  }

  /**
   * Opens this window, creating it first if it has not yet been created.
   * <p>
   * If this window has been configured to block on open (
   * <code>setBlockOnOpen</code>), this method waits until the window is
   * closed by the end user, and then it returns the window's return code;
   * otherwise, this method returns immediately. A window's return codes are
   * window-specific, although two standard return codes are predefined:
   * <code>OK</code> and <code>CANCEL</code>.
   * </p>
   *
   * @return the return code
   *
   * @see #create()
   */
  public int open() {
       
    if (shell == null || shell.isDisposed()) {
            shell = null;
      // create the window
      create();
    }

    // limit the shell size to the display size
    constrainShellSize();

    // open the window
    shell.open();

    // run the event loop if specified
    if (block) {
      runEventLoop(shell);
    }

    return returnCode;
  }

  /**
   * Runs the event loop for the given shell.
   *
   * @param loopShell
   *            the shell
   */
  private void runEventLoop(Shell loopShell) {

    //Use the display provided by the shell if possible
    Display display;
    if (shell == null) {
      display = Display.getCurrent();
    } else {
      display = loopShell.getDisplay();
    }

    while (loopShell != null && !loopShell.isDisposed()) {
      try {
        if (!display.readAndDispatch()) {
          display.sleep();
        }
      } catch (Throwable e) {
        exceptionHandler.handleException(e);
      }
    }
    if (!display.isDisposed()) display.update();
  }

  /**
   * Sets whether the <code>open</code> method should block until the window
   * closes.
   *
   * @param shouldBlock
   *            <code>true</code> if the <code>open</code> method should
   *            not return until the window closes, and <code>false</code>
   *            if the <code>open</code> method should return immediately
   */
  public void setBlockOnOpen(boolean shouldBlock) {
    block = shouldBlock;
  }

  /**
   * Sets the default image. This is the image that will be used for windows
   * that have no shell image at the time they are opened. There is no default
   * image unless one is installed via this method.
   *
   * @param image
   *            the default image, or <code>null</code> if none
   */
  public static void setDefaultImage(Image image) {
    defaultImages = image == null ? null : new Image[] { image };
  }

  /**
   * Sets the array of default images to use for newly opened windows. It is
   * expected that the array will contain the same icon rendered at different
   * resolutions.
   *
   * @see org.eclipse.swt.widgets.Decorations#setImages(org.eclipse.swt.graphics.Image[])
   *
   * @param images
   *            the array of images to be used when this window is opened
   * @since 3.0
   */
  public static void setDefaultImages(Image[] images) {
    Image[] newArray = new Image[images.length];
    System.arraycopy(images, 0, newArray, 0, newArray.length);
    defaultImages = newArray;
  }
 
  /**
     * Changes the parent shell. This is only safe to use when the shell is not
     * yet realized (i.e., created). Once the shell is created, it must be
     * disposed (i.e., closed) before this method can be called.
     *
     * @param newParentShell
     *            The new parent shell; this value may be <code>null</code> if
     *            there is to be no parent.
     * @since 3.1
     */
    protected void setParentShell(final Shell newParentShell) {
        Assert.isTrue((shell == null), "There must not be an existing shell."); //$NON-NLS-1$
        parentShell = new SameShellProvider(newParentShell);
    }

  /**
   * Sets this window's return code. The return code is automatically returned
   * by <code>open</code> if block on open is enabled. For non-blocking
   * opens, the return code needs to be retrieved manually using
   * <code>getReturnCode</code>.
   *
   * @param code
   *            the return code
   */
  protected void setReturnCode(int code) {
    returnCode = code;
  }

  /**
   * Returns the monitor whose client area contains the given point. If no
   * monitor contains the point, returns the monitor that is closest to the
   * point. If this is ever made public, it should be moved into a separate
   * utility class.
   *
   * @param toSearch
   *            point to find (display coordinates)
   * @param toFind
   *            point to find (display coordinates)
   * @return the montor closest to the given point
   */
  private static Monitor getClosestMonitor(Display toSearch, Point toFind) {
    int closest = Integer.MAX_VALUE;

    Monitor[] monitors = toSearch.getMonitors();
    Monitor result = monitors[0];

    for (int idx = 0; idx < monitors.length; idx++) {
      Monitor current = monitors[idx];

      Rectangle clientArea = current.getClientArea();

      if (clientArea.contains(toFind)) {
        return current;
      }

      int distance = Geometry.distanceSquared(Geometry
          .centerPoint(clientArea), toFind);
      if (distance < closest) {
        closest = distance;
        result = current;
      }
    }

    return result;
  }

  /**
   * Given the desired position of the window, this method returns an adjusted
   * position such that the window is no larger than its monitor, and does not
   * extend beyond the edge of the monitor. This is used for computing the
   * initial window position, and subclasses can use this as a utility method
   * if they want to limit the region in which the window may be moved.
   *
   * @param preferredSize
   *            the preferred position of the window
   * @return a rectangle as close as possible to preferredSize that does not
   *         extend outside the monitor
   *
   * @since 3.0
   */
  protected Rectangle getConstrainedShellBounds(Rectangle preferredSize) {
    Rectangle result = new Rectangle(preferredSize.x, preferredSize.y,
        preferredSize.width, preferredSize.height);

    Monitor mon = getClosestMonitor(getShell().getDisplay(), Geometry
        .centerPoint(result));

    Rectangle bounds = mon.getClientArea();

    if (result.height > bounds.height) {
      result.height = bounds.height;
    }

    if (result.width > bounds.width) {
      result.width = bounds.width;
    }

    result.x = Math.max(bounds.x, Math.min(result.x, bounds.x
        + bounds.width - result.width));
    result.y = Math.max(bounds.y, Math.min(result.y, bounds.y
        + bounds.height - result.height));

    return result;
  }

  /**
   * Sets the shell style bits. This method has no effect after the shell is
   * created.
   * <p>
   * The shell style bits are used by the framework method
   * <code>createShell</code> when creating this window's shell.
   * </p>
   *
   * @param newShellStyle
   *            the new shell style bits
   */
  protected void setShellStyle(int newShellStyle) {
    shellStyle = newShellStyle;
  }

  /**
   * Sets the window manager of this window.
   * <p>
   * Note that this method is used by <code>WindowManager</code> to maintain
   * a backpointer. Clients must not call the method directly.
   * </p>
   *
   * @param manager
   *            the window manager, or <code>null</code> if none
   */
  public void setWindowManager(WindowManager manager) {
    windowManager = manager;

    // Code to detect invalid usage

    if (manager != null) {
      Window[] windows = manager.getWindows();
      for (int i = 0; i < windows.length; i++) {
        if (windows[i] == this) {
          return;
        }
      }
      manager.add(this);
    }
  }

  /**
   * Sets the exception handler for this application.
   * <p>
   * Note that the handler may only be set once.  Subsequent calls to this method will be
   * ignored.
   * <p>
   *
   * @param handler
   *            the exception handler for the application.
   */
  public static void setExceptionHandler(IExceptionHandler handler) {
    if (exceptionHandler instanceof DefaultExceptionHandler) {
      exceptionHandler = handler;
    }
  }
   
    /**
     * Sets the default parent for modal Windows. This will be used to locate
     * the parent for any modal Window constructed with a null parent.
     *
     * @param provider shell provider that will be used to locate the parent shell
     * whenever a Window is created with a null parent
     * @since 3.1
     */
    public static void setDefaultModalParent(IShellProvider provider) {
        defaultModalParent = provider;
    }
   
  /**
   * Gets the default orientation for windows. If it is not
   * set the default value will be unspecified (SWT#NONE).
   *
   *
   * @return SWT#NONE, SWT.RIGHT_TO_LEFT or SWT.LEFT_TO_RIGHT
   * @see SWT#RIGHT_TO_LEFT
   * @see SWT#LEFT_TO_RIGHT
   * @see SWT#NONE
   * @since 3.1
   */
  public static int getDefaultOrientation() {
    return orientation;

  }

  /**
   * Sets the default orientation of windows.
   * @param defaultOrientation one of
   *   SWT#RIGHT_TO_LEFT, SWT#LEFT_TO_RIGHT ,SWT#NONE
   * @see SWT#RIGHT_TO_LEFT
   * @see SWT#LEFT_TO_RIGHT
   * @see SWT#NONE
   * @since 3.1
   */
  public static void setDefaultOrientation(int defaultOrientation) {
    orientation = defaultOrientation;
   
  }

}
TOP

Related Classes of org.eclipse.jface.window.Window$DefaultExceptionHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.