KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jface > window > Window


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jface.window;
12
13 import java.util.ArrayList JavaDoc;
14
15 import org.eclipse.jface.resource.JFaceResources;
16 import org.eclipse.core.runtime.Assert;
17 import org.eclipse.jface.util.Geometry;
18 import org.eclipse.jface.util.IPropertyChangeListener;
19 import org.eclipse.jface.util.PropertyChangeEvent;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.events.ShellAdapter;
22 import org.eclipse.swt.events.ShellEvent;
23 import org.eclipse.swt.events.ShellListener;
24 import org.eclipse.swt.graphics.Image;
25 import org.eclipse.swt.graphics.Point;
26 import org.eclipse.swt.graphics.Rectangle;
27 import org.eclipse.swt.layout.GridLayout;
28 import org.eclipse.swt.widgets.Composite;
29 import org.eclipse.swt.widgets.Control;
30 import org.eclipse.swt.widgets.Display;
31 import org.eclipse.swt.widgets.Event;
32 import org.eclipse.swt.widgets.Layout;
33 import org.eclipse.swt.widgets.Listener;
34 import org.eclipse.swt.widgets.Monitor;
35 import org.eclipse.swt.widgets.Shell;
36
37 /**
38  * A JFace window is an object that has no visual representation (no widgets)
39  * until it is told to open.
40  * <p>
41  * Creating a window involves the following steps:
42  * <ul>
43  * <li>creating an instance of a concrete subclass of <code>Window</code>
44  * </li>
45  * <li>creating the window's shell and widget tree by calling
46  * <code>create</code> (optional)</li>
47  * <li>assigning the window to a window manager using
48  * <code>WindowManager.add</code> (optional)</li>
49  * <li>opening the window by calling <code>open</code></li>
50  * </ul>
51  * Opening the window will create its shell and widget tree if they have not
52  * already been created. When the window is closed, the shell and widget tree
53  * are disposed of and are no longer referenced, and the window is automatically
54  * removed from its window manager. A window may be reopened.
55  * </p>
56  * <p>
57  * The JFace window framework (this package) consists of this class,
58  * <code>Window</code>, the abstract base of all windows, and one concrete
59  * window classes (<code>ApplicationWindow</code>) which may also be
60  * subclassed. Clients may define additional window subclasses as required.
61  * </p>
62  * <p>
63  * The <code>Window</code> class provides methods that subclasses may
64  * override to configure the window, including:
65  * <ul>
66  * <li><code>close</code>- extend to free other SWT resources</li>
67  * <li><code>configureShell</code>- extend or reimplement to set shell
68  * properties before window opens</li>
69  * <li><code>createContents</code>- extend or reimplement to create controls
70  * before window opens</li>
71  * <li><code>getInitialSize</code>- reimplement to give the initial size for
72  * the shell</li>
73  * <li><code>getInitialLocation</code>- reimplement to give the initial
74  * location for the shell</li>
75  * <li><code>getShellListener</code>- extend or reimplement to receive shell
76  * events</li>
77  * <li><code>handleFontChange</code>- reimplement to respond to font changes
78  * </li>
79  * <li><code>handleShellCloseEvent</code>- extend or reimplement to handle
80  * shell closings</li>
81  * </ul>
82  * </p>
83  */

84 public abstract class Window implements IShellProvider {
85
86     /**
87      * Standard return code constant (value 0) indicating that the window was
88      * opened.
89      *
90      * @see #open
91      */

92     public static final int OK = 0;
93
94     /**
95      * Standard return code constant (value 1) indicating that the window was
96      * canceled.
97      *
98      * @see #open
99      */

100     public static final int CANCEL = 1;
101
102     /**
103      * An array of images to be used for the window. It is expected that the
104      * array will contain the same icon rendered at different resolutions.
105      */

106     private static Image[] defaultImages;
107
108     /**
109      * This interface defines a Exception Handler which can be set as a global
110      * handler and will be called if an exception happens in the event loop.
111      */

112     public static interface IExceptionHandler {
113         /**
114          * Handle the exception.
115          *
116          * @param t
117          * The exception that occured.
118          */

119         public void handleException(Throwable JavaDoc t);
120     }
121
122     /**
123      * Defines a default exception handler.
124      */

125     private static class DefaultExceptionHandler implements IExceptionHandler {
126         /*
127          * (non-Javadoc)
128          *
129          * @see org.eclipse.jface.window.Window.IExceptionHandler#handleException(java.lang.Throwable)
130          */

131         public void handleException(Throwable JavaDoc t) {
132             if (t instanceof ThreadDeath JavaDoc) {
133                 // Don't catch ThreadDeath as this is a normal occurrence when
134
// the thread dies
135
throw (ThreadDeath JavaDoc) t;
136             }
137             // Try to keep running.
138
t.printStackTrace();
139         }
140     }
141
142     /**
143      * The exception handler for this application.
144      */

145     private static IExceptionHandler exceptionHandler = new DefaultExceptionHandler();
146     
147     /**
148      * The default orientation of the window. By default
149      * it is SWT#NONE but it can also be SWT#LEFT_TO_RIGHT
150      * or SWT#RIGHT_TO_LEFT
151      */

152     private static int orientation = SWT.NONE;
153
154     /**
155      * Object used to locate the default parent for modal shells
156      */

157     private static IShellProvider defaultModalParent = new IShellProvider() {
158         public Shell getShell() {
159             Display d = Display.getCurrent();
160             
161             if (d == null) {
162                 return null;
163             }
164
165             Shell parent = d.getActiveShell();
166             
167             // Make sure we don't pick a parent that has a modal child (this can lock the app)
168
if (parent == null) {
169                 // If this is a top-level window, then there must not be any open modal windows.
170
parent = getModalChild(Display.getCurrent().getShells());
171             } else {
172                 // If we picked a parent with a modal child, use the modal child instead
173
Shell modalChild = getModalChild(parent.getShells());
174                 if (modalChild != null) {
175                     parent = modalChild;
176                 }
177             }
178             
179             return parent;
180         }
181     };
182     
183     /**
184      * Object that returns the parent shell.
185      */

186     private IShellProvider parentShell;
187
188     /**
189      * Shell style bits.
190      *
191      * @see #setShellStyle
192      */

193     private int shellStyle = SWT.SHELL_TRIM;
194
195     /**
196      * Window manager, or <code>null</code> if none.
197      *
198      * @see #setWindowManager
199      */

200     private WindowManager windowManager;
201
202     /**
203      * Window shell, or <code>null</code> if none.
204      */

205     private Shell shell;
206
207     /**
208      * Top level SWT control, or <code>null</code> if none
209      */

210     private Control contents;
211
212     /**
213      * Window return code; initially <code>OK</code>.
214      *
215      * @see #setReturnCode
216      */

217     private int returnCode = OK;
218
219     /**
220      * <code>true</code> if the <code>open</code> method should not return
221      * until the window closes, and <code>false</code> if the
222      * <code>open</code> method should return immediately; initially
223      * <code>false</code> (non-blocking).
224      *
225      * @see #setBlockOnOpen
226      */

227     private boolean block = false;
228
229     /**
230      * Internal class for informing this window when fonts change.
231      */

232     private class FontChangeListener implements IPropertyChangeListener {
233         public void propertyChange(PropertyChangeEvent event) {
234             handleFontChange(event);
235         }
236     }
237
238     /**
239      * Internal font change listener.
240      */

241     private FontChangeListener fontChangeListener;
242
243     /**
244      * Internal fields to detect if shell size has been set
245      */

246     private boolean resizeHasOccurred = false;
247
248     private Listener resizeListener;
249  
250     /**
251      * Creates a window instance, whose shell will be created under the given
252      * parent shell. Note that the window will have no visual representation
253      * until it is told to open. By default, <code>open</code> does not block.
254      *
255      * @param parentShell
256      * the parent shell, or <code>null</code> to create a top-level
257      * shell. Try passing "(Shell)null" to this method instead of "null"
258      * if your compiler complains about an ambiguity error.
259      * @see #setBlockOnOpen
260      * @see #getDefaultOrientation()
261      */

262     protected Window(Shell parentShell) {
263         this(new SameShellProvider(parentShell));
264         
265         if(parentShell == null) {
266             setShellStyle(getShellStyle() | getDefaultOrientation());
267         }
268     }
269     
270     /**
271      * Creates a new window which will create its shell as a child of whatever
272      * the given shellProvider returns.
273      *
274      * @param shellProvider object that will return the current parent shell. Not null.
275      *
276      * @since 3.1
277      */

278     protected Window(IShellProvider shellProvider) {
279         Assert.isNotNull(shellProvider);
280         this.parentShell = shellProvider;
281     }
282
283     /**
284      * Determines if the window should handle the close event or do nothing.
285      * <p>
286      * The default implementation of this framework method returns
287      * <code>true</code>, which will allow the
288      * <code>handleShellCloseEvent</code> method to be called. Subclasses may
289      * extend or reimplement.
290      * </p>
291      *
292      * @return whether the window should handle the close event.
293      */

294     protected boolean canHandleShellCloseEvent() {
295         return true;
296     }
297
298     /**
299      * Closes this window, disposes its shell, and removes this window from its
300      * window manager (if it has one).
301      * <p>
302      * This framework method may be extended (<code>super.close</code> must
303      * be called).
304      * </p>
305      *
306      * @return <code>true</code> if the window is (or was already) closed, and
307      * <code>false</code> if it is still open
308      */

309     public boolean close() {
310         
311         // stop listening for font changes
312
if (fontChangeListener != null) {
313             JFaceResources.getFontRegistry().removeListener(fontChangeListener);
314             fontChangeListener = null;
315         }
316         
317         // remove this window from a window manager if it has one
318
if (windowManager != null) {
319             windowManager.remove(this);
320             windowManager = null;
321         }
322
323         if (shell == null || shell.isDisposed()) {
324             return true;
325         }
326
327         // If we "close" the shell recursion will occur.
328
// Instead, we need to "dispose" the shell to remove it from the
329
// display.
330
shell.dispose();
331         shell = null;
332         contents = null;
333
334         return true;
335     }
336
337     /**
338      * Configures the given shell in preparation for opening this window in it.
339      * <p>
340      * The default implementation of this framework method sets the shell's
341      * image and gives it a grid layout. Subclasses may extend or reimplement.
342      * </p>
343      *
344      * @param newShell
345      * the shell
346      */

347     protected void configureShell(Shell newShell) {
348
349         // The single image version of this code had a comment related to bug
350
// 46624,
351
// and some code that did nothing if the stored image was already
352
// disposed.
353
// The equivalent in the multi-image version seems to be to remove the
354
// disposed images from the array passed to the shell.
355
if (defaultImages != null && defaultImages.length > 0) {
356             ArrayList JavaDoc nonDisposedImages = new ArrayList JavaDoc(defaultImages.length);
357             for (int i = 0; i < defaultImages.length; ++i) {
358                 if (defaultImages[i] != null && !defaultImages[i].isDisposed()) {
359                     nonDisposedImages.add(defaultImages[i]);
360                 }
361             }
362
363             if (nonDisposedImages.size() <= 0) {
364                 System.err.println("Window.configureShell: images disposed"); //$NON-NLS-1$
365
} else {
366                 Image[] array = new Image[nonDisposedImages.size()];
367                 nonDisposedImages.toArray(array);
368                 newShell.setImages(array);
369             }
370         }
371
372         Layout layout = getLayout();
373         if (layout != null) {
374             newShell.setLayout(layout);
375         }
376     }
377
378     /**
379      * Creates the layout for the shell. The layout created here will be
380      * attached to the composite passed into createContents. The default
381      * implementation returns a GridLayout with no margins. Subclasses that
382      * change the layout type by overriding this method should also override
383      * createContents.
384      *
385      * <p>
386      * A return value of null indicates that no layout should be attached to the
387      * composite. In this case, the layout may be attached within
388      * createContents.
389      * </p>
390      *
391      * @return a newly created Layout or null if no layout should be attached.
392      * @since 3.0
393      */

394     protected Layout getLayout() {
395         GridLayout layout = new GridLayout();
396         layout.marginHeight = 0;
397         layout.marginWidth = 0;
398         return layout;
399     }
400
401     /**
402      * Constrain the shell size to be no larger than the display bounds.
403      *
404      * @since 2.0
405      */

406     protected void constrainShellSize() {
407         // limit the shell size to the display size
408
Rectangle bounds = shell.getBounds();
409         Rectangle constrained = getConstrainedShellBounds(bounds);
410         if (!bounds.equals(constrained)) {
411             shell.setBounds(constrained);
412         }
413     }
414
415     /**
416      * Creates this window's widgetry in a new top-level shell.
417      * <p>
418      * The default implementation of this framework method creates this window's
419      * shell (by calling <code>createShell</code>), and its controls (by
420      * calling <code>createContents</code>), then initializes this window's
421      * shell bounds (by calling <code>initializeBounds</code>).
422      * </p>
423      */

424     public void create() {
425         shell = createShell();
426         contents = createContents(shell);
427
428         //initialize the bounds of the shell to that appropriate for the
429
// contents
430
initializeBounds();
431     }
432
433     /**
434      * Creates and returns this window's contents. Subclasses may attach any
435      * number of children to the parent. As a convenience, the return value of
436      * this method will be remembered and returned by subsequent calls to
437      * getContents(). Subclasses may modify the parent's layout if they overload
438      * getLayout() to return null.
439      *
440      * <p>
441      * It is common practise to create and return a single composite that
442      * contains the entire window contents.
443      * </p>
444      *
445      * <p>
446      * The default implementation of this framework method creates an instance
447      * of <code>Composite</code>. Subclasses may override.
448      * </p>
449      *
450      * @param parent
451      * the parent composite for the controls in this window. The type
452      * of layout used is determined by getLayout()
453      *
454      * @return the control that will be returned by subsequent calls to
455      * getContents()
456      */

457     protected Control createContents(Composite parent) {
458         // by default, just create a composite
459
return new Composite(parent, SWT.NONE);
460     }
461
462     /**
463      * Creates and returns this window's shell.
464      * <p>
465      * The default implementation of this framework method creates a new shell
466      * and configures it using <code/>configureShell</code>. Rather than
467      * override this method, subclasses should instead override
468      * <code/>configureShell</code>.
469      * </p>
470      *
471      * @return the shell
472      */

473     protected final Shell createShell() {
474
475         Shell newParent = getParentShell();
476         if(newParent != null && newParent.isDisposed()){
477             parentShell = new SameShellProvider(null);
478             newParent = getParentShell();//Find a better parent
479
}
480         
481         //Create the shell
482
Shell newShell = new Shell(newParent, getShellStyle());
483
484         resizeListener = new Listener() {
485             public void handleEvent(Event e) {
486                 resizeHasOccurred = true;
487             }
488         };
489
490         newShell.addListener(SWT.Resize, resizeListener);
491         newShell.setData(this);
492
493         //Add a listener
494
newShell.addShellListener(getShellListener());
495
496         //Set the layout
497
configureShell(newShell);
498
499         //Register for font changes
500
if (fontChangeListener == null) {
501             fontChangeListener = new FontChangeListener();
502         }
503         JFaceResources.getFontRegistry().addListener(fontChangeListener);
504
505         return newShell;
506     }
507
508     /**
509      * Returns the top level control for this window. The parent of this control
510      * is the shell.
511      *
512      * @return the top level control, or <code>null</code> if this window's
513      * control has not been created yet
514      */

515     protected Control getContents() {
516         return contents;
517     }
518
519     /**
520      * Returns the default image. This is the image that will be used for
521      * windows that have no shell image at the time they are opened. There is no
522      * default image unless one is installed via <code>setDefaultImage</code>.
523      *
524      * @return the default image, or <code>null</code> if none
525      * @see #setDefaultImage
526      */

527     public static Image getDefaultImage() {
528         return (defaultImages == null || defaultImages.length < 1) ? null
529                 : defaultImages[0];
530     }
531
532     /**
533      * Returns the array of default images to use for newly opened windows. It
534      * is expected that the array will contain the same icon rendered at
535      * different resolutions.
536      *
537      * @see org.eclipse.swt.widgets.Decorations#setImages(org.eclipse.swt.graphics.Image[])
538      *
539      * @return the array of images to be used when a new window is opened
540      * @see #setDefaultImages
541      * @since 3.0
542      */

543     public static Image[] getDefaultImages() {
544         return (defaultImages == null ? new Image[0] : defaultImages);
545     }
546
547     /**
548      * Returns the initial location to use for the shell. The default
549      * implementation centers the shell horizontally (1/2 of the difference to
550      * the left and 1/2 to the right) and vertically (1/3 above and 2/3 below)
551      * relative to the parent shell, or display bounds if there is no parent
552      * shell.
553      *
554      * @param initialSize
555      * the initial size of the shell, as returned by
556      * <code>getInitialSize</code>.
557      * @return the initial location of the shell
558      */

559     protected Point getInitialLocation(Point initialSize) {
560         Composite parent = shell.getParent();
561
562         Monitor monitor = shell.getDisplay().getPrimaryMonitor();
563         if (parent != null) {
564             monitor = parent.getMonitor();
565         }
566
567         Rectangle monitorBounds = monitor.getClientArea();
568         Point centerPoint;
569         if (parent != null) {
570             centerPoint = Geometry.centerPoint(parent.getBounds());
571         } else {
572             centerPoint = Geometry.centerPoint(monitorBounds);
573         }
574
575         return new Point(centerPoint.x - (initialSize.x / 2), Math.max(
576                 monitorBounds.y, Math.min(centerPoint.y
577                         - (initialSize.y * 2 / 3), monitorBounds.y
578                         + monitorBounds.height - initialSize.y)));
579     }
580
581     /**
582      * Returns the initial size to use for the shell. The default implementation
583      * returns the preferred size of the shell, using
584      * <code>Shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true)</code>.
585      *
586      * @return the initial size of the shell
587      */

588     protected Point getInitialSize() {
589         return shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
590     }
591
592     /**
593      * Returns the most specific modal child from the given list of Shells.
594      *
595      * @param toSearch shells to search for modal children
596      * @return the most specific modal child, or null if none
597      *
598      * @since 3.1
599      */

600     private static Shell getModalChild(Shell[] toSearch) {
601         int modal = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL | SWT.PRIMARY_MODAL;
602         
603         for (int i = toSearch.length - 1; i >= 0; i--) {
604             Shell shell = toSearch[i];
605             
606             // Check if this shell has a modal child
607
Shell[] children = shell.getShells();
608             Shell modalChild = getModalChild(children);
609             if (modalChild != null) {
610                 return modalChild;
611             }
612             
613             // If not, check if this shell is modal itself
614
if (shell.isVisible() && (shell.getStyle() & modal) != 0) {
615                 return shell;
616             }
617         }
618         
619         return null;
620     }
621     
622     /**
623      * Returns parent shell, under which this window's shell is created.
624      *
625      * @return the parent shell, or <code>null</code> if there is no parent
626      * shell
627      */

628     protected Shell getParentShell() {
629         Shell parent = parentShell.getShell();
630         
631         int modal = SWT.APPLICATION_MODAL | SWT.SYSTEM_MODAL | SWT.PRIMARY_MODAL;
632         
633         if ((getShellStyle() & modal) != 0) {
634             // If this is a modal shell with no parent, pick a shell using defaultModalParent.
635
if (parent == null) {
636                 parent = defaultModalParent.getShell();
637             }
638         }
639         
640         return parent;
641     }
642
643     /**
644      * Returns this window's return code. A window's return codes are
645      * window-specific, although two standard return codes are predefined:
646      * <code>OK</code> and <code>CANCEL</code>.
647      *
648      * @return the return code
649      */

650     public int getReturnCode() {
651         return returnCode;
652     }
653
654     /**
655      * Returns this window's shell.
656      *
657      * @return this window's shell, or <code>null</code> if this window's
658      * shell has not been created yet
659      */

660     public Shell getShell() {
661         return shell;
662     }
663
664     /**
665      * Returns a shell listener. This shell listener gets registered with this
666      * window's shell.
667      * <p>
668      * The default implementation of this framework method returns a new
669      * listener that makes this window the active window for its window manager
670      * (if it has one) when the shell is activated, and calls the framework
671      * method <code>handleShellCloseEvent</code> when the shell is closed.
672      * Subclasses may extend or reimplement.
673      * </p>
674      *
675      * @return a shell listener
676      */

677     protected ShellListener getShellListener() {
678         return new ShellAdapter() {
679             public void shellClosed(ShellEvent event) {
680                 event.doit = false; // don't close now
681
if (canHandleShellCloseEvent()) {
682                     handleShellCloseEvent();
683                 }
684             }
685         };
686     }
687
688     /**
689      * Returns the shell style bits.
690      * <p>
691      * The default value is <code>SWT.CLOSE|SWT.MIN|SWT.MAX|SWT.RESIZE</code>.
692      * Subclassers should call <code>setShellStyle</code> to change this
693      * value, rather than overriding this method.
694      * </p>
695      *
696      * @return the shell style bits
697      */

698     protected int getShellStyle() {
699         return shellStyle;
700     }
701
702     /**
703      * Returns the window manager of this window.
704      *
705      * @return the WindowManager, or <code>null</code> if none
706      */

707     public WindowManager getWindowManager() {
708         return windowManager;
709     }
710
711     /**
712      * Notifies of a font property change.
713      * <p>
714      * The default implementation of this framework method does nothing.
715      * Subclasses may reimplement.
716      * </p>
717      *
718      * @param event
719      * the property change event detailing what changed
720      */

721     protected void handleFontChange(PropertyChangeEvent event) {
722         // do nothing
723
}
724
725     /**
726      * Notifies that the window's close button was pressed, the close menu was
727      * selected, or the ESCAPE key pressed.
728      * <p>
729      * The default implementation of this framework method sets the window's
730      * return code to <code>CANCEL</code> and closes the window using
731      * <code>close</code>. Subclasses may extend or reimplement.
732      * </p>
733      */

734     protected void handleShellCloseEvent() {
735         setReturnCode(CANCEL);
736         close();
737     }
738
739     /**
740      * Initializes the location and size of this window's SWT shell after it has
741      * been created.
742      * <p>
743      * This framework method is called by the <code>create</code> framework
744      * method. The default implementation calls <code>getInitialSize</code>
745      * and <code>getInitialLocation</code> and passes the results to
746      * <code>Shell.setBounds</code>. This is only done if the bounds of the
747      * shell have not already been modified. Subclasses may extend or
748      * reimplement.
749      * </p>
750      */

751     protected void initializeBounds() {
752         if (resizeListener != null) {
753             shell.removeListener(SWT.Resize, resizeListener);
754         }
755         if (resizeHasOccurred) { // Check if shell size has been set already.
756
return;
757         }
758
759         Point size = getInitialSize();
760         Point location = getInitialLocation(size);
761         shell.setBounds(getConstrainedShellBounds(new Rectangle(location.x,
762                 location.y, size.x, size.y)));
763     }
764
765     /**
766      * Opens this window, creating it first if it has not yet been created.
767      * <p>
768      * If this window has been configured to block on open (
769      * <code>setBlockOnOpen</code>), this method waits until the window is
770      * closed by the end user, and then it returns the window's return code;
771      * otherwise, this method returns immediately. A window's return codes are
772      * window-specific, although two standard return codes are predefined:
773      * <code>OK</code> and <code>CANCEL</code>.
774      * </p>
775      *
776      * @return the return code
777      *
778      * @see #create()
779      */

780     public int open() {
781         
782         if (shell == null || shell.isDisposed()) {
783             shell = null;
784             // create the window
785
create();
786         }
787
788         // limit the shell size to the display size
789
constrainShellSize();
790
791         // open the window
792
shell.open();
793
794         // run the event loop if specified
795
if (block) {
796             runEventLoop(shell);
797         }
798
799         return returnCode;
800     }
801
802     /**
803      * Runs the event loop for the given shell.
804      *
805      * @param loopShell
806      * the shell
807      */

808     private void runEventLoop(Shell loopShell) {
809
810         //Use the display provided by the shell if possible
811
Display display;
812         if (shell == null) {
813             display = Display.getCurrent();
814         } else {
815             display = loopShell.getDisplay();
816         }
817
818         while (loopShell != null && !loopShell.isDisposed()) {
819             try {
820                 if (!display.readAndDispatch()) {
821                     display.sleep();
822                 }
823             } catch (Throwable JavaDoc e) {
824                 exceptionHandler.handleException(e);
825             }
826         }
827         display.update();
828     }
829
830     /**
831      * Sets whether the <code>open</code> method should block until the window
832      * closes.
833      *
834      * @param shouldBlock
835      * <code>true</code> if the <code>open</code> method should
836      * not return until the window closes, and <code>false</code>
837      * if the <code>open</code> method should return immediately
838      */

839     public void setBlockOnOpen(boolean shouldBlock) {
840         block = shouldBlock;
841     }
842
843     /**
844      * Sets the default image. This is the image that will be used for windows
845      * that have no shell image at the time they are opened. There is no default
846      * image unless one is installed via this method.
847      *
848      * @param image
849      * the default image, or <code>null</code> if none
850      */

851     public static void setDefaultImage(Image image) {
852         defaultImages = image == null ? null : new Image[] { image };
853     }
854
855     /**
856      * Sets the array of default images to use for newly opened windows. It is
857      * expected that the array will contain the same icon rendered at different
858      * resolutions.
859      *
860      * @see org.eclipse.swt.widgets.Decorations#setImages(org.eclipse.swt.graphics.Image[])
861      *
862      * @param images
863      * the array of images to be used when this window is opened
864      * @since 3.0
865      */

866     public static void setDefaultImages(Image[] images) {
867         Image[] newArray = new Image[images.length];
868         System.arraycopy(images, 0, newArray, 0, newArray.length);
869         defaultImages = newArray;
870     }
871     
872     /**
873      * Changes the parent shell. This is only safe to use when the shell is not
874      * yet realized (i.e., created). Once the shell is created, it must be
875      * disposed (i.e., closed) before this method can be called.
876      *
877      * @param newParentShell
878      * The new parent shell; this value may be <code>null</code> if
879      * there is to be no parent.
880      * @since 3.1
881      */

882     protected void setParentShell(final Shell newParentShell) {
883         Assert.isTrue((shell == null), "There must not be an existing shell."); //$NON-NLS-1$
884
parentShell = new SameShellProvider(newParentShell);
885     }
886
887     /**
888      * Sets this window's return code. The return code is automatically returned
889      * by <code>open</code> if block on open is enabled. For non-blocking
890      * opens, the return code needs to be retrieved manually using
891      * <code>getReturnCode</code>.
892      *
893      * @param code
894      * the return code
895      */

896     protected void setReturnCode(int code) {
897         returnCode = code;
898     }
899
900     /**
901      * Returns the monitor whose client area contains the given point. If no
902      * monitor contains the point, returns the monitor that is closest to the
903      * point. If this is ever made public, it should be moved into a separate
904      * utility class.
905      *
906      * @param toSearch
907      * point to find (display coordinates)
908      * @param toFind
909      * point to find (display coordinates)
910      * @return the montor closest to the given point
911      */

912     private static Monitor getClosestMonitor(Display toSearch, Point toFind) {
913         int closest = Integer.MAX_VALUE;
914
915         Monitor[] monitors = toSearch.getMonitors();
916         Monitor result = monitors[0];
917
918         for (int idx = 0; idx < monitors.length; idx++) {
919             Monitor current = monitors[idx];
920
921             Rectangle clientArea = current.getClientArea();
922
923             if (clientArea.contains(toFind)) {
924                 return current;
925             }
926
927             int distance = Geometry.distanceSquared(Geometry
928                     .centerPoint(clientArea), toFind);
929             if (distance < closest) {
930                 closest = distance;
931                 result = current;
932             }
933         }
934
935         return result;
936     }
937
938     /**
939      * Given the desired position of the window, this method returns an adjusted
940      * position such that the window is no larger than its monitor, and does not
941      * extend beyond the edge of the monitor. This is used for computing the
942      * initial window position, and subclasses can use this as a utility method
943      * if they want to limit the region in which the window may be moved.
944      *
945      * @param preferredSize
946      * the preferred position of the window
947      * @return a rectangle as close as possible to preferredSize that does not
948      * extend outside the monitor
949      *
950      * @since 3.0
951      */

952     protected Rectangle getConstrainedShellBounds(Rectangle preferredSize) {
953         Rectangle result = new Rectangle(preferredSize.x, preferredSize.y,
954                 preferredSize.width, preferredSize.height);
955
956         Monitor mon = getClosestMonitor(getShell().getDisplay(), Geometry
957                 .centerPoint(result));
958
959         Rectangle bounds = mon.getClientArea();
960
961         if (result.height > bounds.height) {
962             result.height = bounds.height;
963         }
964
965         if (result.width > bounds.width) {
966             result.width = bounds.width;
967         }
968
969         result.x = Math.max(bounds.x, Math.min(result.x, bounds.x
970                 + bounds.width - result.width));
971         result.y = Math.max(bounds.y, Math.min(result.y, bounds.y
972                 + bounds.height - result.height));
973
974         return result;
975     }
976
977     /**
978      * Sets the shell style bits. This method has no effect after the shell is
979      * created.
980      * <p>
981      * The shell style bits are used by the framework method
982      * <code>createShell</code> when creating this window's shell.
983      * </p>
984      *
985      * @param newShellStyle
986      * the new shell style bits
987      */

988     protected void setShellStyle(int newShellStyle) {
989         shellStyle = newShellStyle;
990     }
991
992     /**
993      * Sets the window manager of this window.
994      * <p>
995      * Note that this method is used by <code>WindowManager</code> to maintain
996      * a backpointer. Clients must not call the method directly.
997      * </p>
998      *
999      * @param manager
1000     * the window manager, or <code>null</code> if none
1001     */

1002    public void setWindowManager(WindowManager manager) {
1003        windowManager = manager;
1004
1005        // Code to detect invalid usage
1006

1007        if (manager != null) {
1008            Window[] windows = manager.getWindows();
1009            for (int i = 0; i < windows.length; i++) {
1010                if (windows[i] == this) {
1011                    return;
1012                }
1013            }
1014            manager.add(this);
1015        }
1016    }
1017
1018    /**
1019     * Sets the exception handler for this application.
1020     * <p>
1021     * Note that the handler may only be set once. Subsequent calls to this method will be
1022     * ignored.
1023     * <p>
1024     *
1025     * @param handler
1026     * the exception handler for the application.
1027     */

1028    public static void setExceptionHandler(IExceptionHandler handler) {
1029        if (exceptionHandler instanceof DefaultExceptionHandler) {
1030            exceptionHandler = handler;
1031        }
1032    }
1033    
1034    /**
1035     * Sets the default parent for modal Windows. This will be used to locate
1036     * the parent for any modal Window constructed with a null parent.
1037     *
1038     * @param provider shell provider that will be used to locate the parent shell
1039     * whenever a Window is created with a null parent
1040     * @since 3.1
1041     */

1042    public static void setDefaultModalParent(IShellProvider provider) {
1043        defaultModalParent = provider;
1044    }
1045    
1046    /**
1047     * Gets the default orientation for windows. If it is not
1048     * set the default value will be unspecified (SWT#NONE).
1049     *
1050     *
1051     * @return SWT#NONE, SWT.RIGHT_TO_LEFT or SWT.LEFT_TO_RIGHT
1052     * @see SWT#RIGHT_TO_LEFT
1053     * @see SWT#LEFT_TO_RIGHT
1054     * @see SWT#NONE
1055     * @since 3.1
1056     */

1057    public static int getDefaultOrientation() {
1058        return orientation;
1059
1060    }
1061
1062    /**
1063     * Sets the default orientation of windows.
1064     * @param defaultOrientation one of
1065     * SWT#RIGHT_TO_LEFT, SWT#LEFT_TO_RIGHT ,SWT#NONE
1066     * @see SWT#RIGHT_TO_LEFT
1067     * @see SWT#LEFT_TO_RIGHT
1068     * @see SWT#NONE
1069     * @since 3.1
1070     */

1071    public static void setDefaultOrientation(int defaultOrientation) {
1072        orientation = defaultOrientation;
1073        
1074    }
1075
1076}
1077
Popular Tags