1 package org
.argeo
.eclipse
.ui
.dialogs
;
3 import org
.apache
.commons
.logging
.Log
;
4 import org
.apache
.commons
.logging
.LogFactory
;
5 import org
.argeo
.eclipse
.ui
.EclipseUiException
;
6 import org
.eclipse
.swt
.SWT
;
7 import org
.eclipse
.swt
.events
.FocusEvent
;
8 import org
.eclipse
.swt
.events
.FocusListener
;
9 import org
.eclipse
.swt
.events
.ShellAdapter
;
10 import org
.eclipse
.swt
.events
.ShellEvent
;
11 import org
.eclipse
.swt
.graphics
.Point
;
12 import org
.eclipse
.swt
.graphics
.Rectangle
;
13 import org
.eclipse
.swt
.layout
.GridData
;
14 import org
.eclipse
.swt
.layout
.GridLayout
;
15 import org
.eclipse
.swt
.widgets
.Composite
;
16 import org
.eclipse
.swt
.widgets
.Control
;
17 import org
.eclipse
.swt
.widgets
.Display
;
18 import org
.eclipse
.swt
.widgets
.Shell
;
20 /** Generic lightweight dialog, not based on JFace. */
22 public class LightweightDialog
{
23 private final static Log log
= LogFactory
.getLog(LightweightDialog
.class);
25 // must be the same value as org.eclipse.jface.window.Window#OK
26 public final static int OK
= 0;
27 // must be the same value as org.eclipse.jface.window.Window#CANCEL
28 public final static int CANCEL
= 1;
30 private Shell parentShell
;
31 private Shell backgroundShell
;
32 private Shell foregoundShell
;
34 private Integer returnCode
= null;
35 private boolean block
= true;
39 /** Tries to find a display */
40 private static Display
getDisplay() {
42 Display display
= Display
.getCurrent();
46 return Display
.getDefault();
47 } catch (Exception e
) {
48 return Display
.getCurrent();
52 public LightweightDialog(Shell parentShell
) {
53 this.parentShell
= parentShell
;
57 if (foregoundShell
!= null)
58 throw new EclipseUiException("There is already a shell");
59 backgroundShell
= new Shell(parentShell
, SWT
.ON_TOP
);
60 backgroundShell
.setFullScreen(true);
61 // if (parentShell != null) {
62 // backgroundShell.setBounds(parentShell.getBounds());
64 // backgroundShell.setMaximized(true);
65 backgroundShell
.setAlpha(128);
66 backgroundShell
.setBackground(getDisplay().getSystemColor(SWT
.COLOR_BLACK
));
67 foregoundShell
= new Shell(backgroundShell
, SWT
.NO_TRIM
| SWT
.ON_TOP
);
70 foregoundShell
.setLayout(new GridLayout());
71 foregoundShell
.setSize(getInitialSize());
72 createDialogArea(foregoundShell
);
76 Rectangle shellBounds
= parentShell
!= null ? parentShell
.getBounds() : Display
.getCurrent().getBounds();// RAP
77 Point dialogSize
= foregoundShell
.getSize();
78 int x
= shellBounds
.x
+ (shellBounds
.width
- dialogSize
.x
) / 2;
79 int y
= shellBounds
.y
+ (shellBounds
.height
- dialogSize
.y
) / 2;
80 foregoundShell
.setLocation(x
, y
);
82 foregoundShell
.addShellListener(new ShellAdapter() {
83 private static final long serialVersionUID
= -2701270481953688763L;
86 public void shellDeactivated(ShellEvent e
) {
89 if (returnCode
== null)// not yet closed
94 public void shellClosed(ShellEvent e
) {
100 backgroundShell
.open();
101 foregoundShell
.open();
102 // after the foreground shell has been opened
103 backgroundShell
.addFocusListener(new FocusListener() {
104 private static final long serialVersionUID
= 3137408447474661070L;
107 public void focusLost(FocusEvent event
) {
111 public void focusGained(FocusEvent event
) {
112 if (hasChildShells())
114 if (returnCode
== null)// not yet closed
122 if (returnCode
== null)
127 public void block() {
129 runEventLoop(foregoundShell
);
130 } catch (ThreadDeath t
) {
132 if (log
.isTraceEnabled())
133 log
.error("Thread death, canceling dialog", t
);
134 } catch (Throwable t
) {
136 log
.error("Cannot open blocking lightweight dialog", t
);
140 private boolean hasChildShells() {
141 if (foregoundShell
== null)
143 return foregoundShell
.getShells().length
!= 0;
146 // public synchronized int openAndWait() {
148 // while (returnCode == null)
151 // } catch (InterruptedException e) {
154 // return returnCode;
157 private synchronized void notifyClose() {
158 if (returnCode
== null)
163 protected void closeShell(int returnCode
) {
164 this.returnCode
= returnCode
;
165 if (CANCEL
== returnCode
)
167 if (foregoundShell
!= null && !foregoundShell
.isDisposed()) {
168 foregoundShell
.close();
169 foregoundShell
.dispose();
170 foregoundShell
= null;
173 if (backgroundShell
!= null && !backgroundShell
.isDisposed()) {
174 backgroundShell
.close();
175 backgroundShell
.dispose();
179 protected Point
getInitialSize() {
180 // if (exception != null)
181 // return new Point(800, 600);
183 return new Point(600, 400);
186 protected Control
createDialogArea(Composite parent
) {
187 Composite dialogarea
= new Composite(parent
, SWT
.NONE
);
188 dialogarea
.setLayout(new GridLayout());
189 dialogarea
.setLayoutData(new GridData(SWT
.FILL
, SWT
.FILL
, true, true));
193 protected Shell
getBackgroundShell() {
194 return backgroundShell
;
197 protected Shell
getForegoundShell() {
198 return foregoundShell
;
201 public void setBlockOnOpen(boolean shouldBlock
) {
206 foregoundShell
.pack();
209 private void runEventLoop(Shell loopShell
) {
211 if (foregoundShell
== null) {
212 display
= Display
.getCurrent();
214 display
= loopShell
.getDisplay();
217 while (loopShell
!= null && !loopShell
.isDisposed()) {
219 if (!display
.readAndDispatch()) {
222 } catch (UnsupportedOperationException e
) {
224 } catch (Throwable e
) {
228 if (!display
.isDisposed())
232 protected void handleException(Throwable t
) {
233 if (t
instanceof ThreadDeath
) {
234 // Don't catch ThreadDeath as this is a normal occurrence when
236 throw (ThreadDeath
) t
;
238 // Try to keep running.
242 /** @return false, if the dialog should not be closed. */
243 protected boolean onCancel() {
247 public void setTitle(String title
) {
249 if (title
!= null && getForegoundShell() != null)
250 getForegoundShell().setText(title
);
253 public Integer
getReturnCode() {