blob: 238b493d35fdfd95d1af2f975577ed73c5ee343a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2005 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.jface.util.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)//Inherit the style from the parent if there is one
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>
*
* @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
* getControl(). 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
* getControl()
*/
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>
* The default implementation of this framework method creates a new shell
* and configures it using <code/>configureShell</code>. Rather than
* override this method, subclasses should instead override
* <code/>configureShell</code>.
* </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);
}
}
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 only one handler may be set. Other 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;
}
}