View Javadoc

1   /*
2    *  MicroEmulator
3    *  Copyright (C) 2002-2003 Bartek Teodorczyk <barteo@barteo.net>
4    *
5    *  This library is free software; you can redistribute it and/or
6    *  modify it under the terms of the GNU Lesser General Public
7    *  License as published by the Free Software Foundation; either
8    *  version 2.1 of the License, or (at your option) any later version.
9    *
10   *  This library is distributed in the hope that it will be useful,
11   *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   *  Lesser General Public License for more details.
14   *
15   *  You should have received a copy of the GNU Lesser General Public
16   *  License along with this library; if not, write to the Free Software
17   *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   */
19  
20  package org.microemu.app.ui.swt;
21  
22  import org.eclipse.swt.SWT;
23  import org.eclipse.swt.events.SelectionAdapter;
24  import org.eclipse.swt.events.SelectionEvent;
25  import org.eclipse.swt.events.ShellAdapter;
26  import org.eclipse.swt.events.ShellEvent;
27  import org.eclipse.swt.events.ShellListener;
28  import org.eclipse.swt.graphics.Point;
29  import org.eclipse.swt.graphics.Rectangle;
30  import org.eclipse.swt.layout.GridData;
31  import org.eclipse.swt.layout.GridLayout;
32  import org.eclipse.swt.widgets.Button;
33  import org.eclipse.swt.widgets.Composite;
34  import org.eclipse.swt.widgets.Control;
35  import org.eclipse.swt.widgets.Display;
36  import org.eclipse.swt.widgets.Event;
37  import org.eclipse.swt.widgets.Listener;
38  import org.eclipse.swt.widgets.Shell;
39  
40  
41  public abstract class SwtDialog
42  {
43  	public static final int OK = 0;
44  	public static final int CANCEL = 1;
45  
46  	private Shell parentShell;
47  	private Shell shell;
48  	
49  	protected Control dialogArea;
50  	protected Control buttonBar;
51  	
52  	protected Button btOk;
53  	protected Button btCancel;
54  
55  	private boolean resizeHasOccurred = false;
56  	private Listener resizeListener;
57  	private Control contents;
58  	private int shellStyle = SWT.SHELL_TRIM;
59  	private boolean block = false;
60  	private int returnCode = OK;
61  
62  
63  	public SwtDialog(Shell parentShell)
64  	{
65  		this.parentShell = parentShell;
66  		this.block = true;
67  		this.shellStyle = SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL;
68  	}
69  	
70  	
71  	public void create() 
72  	{
73  		shell = createShell();
74  		contents = createContents(shell);
75  
76  		//initialize the bounds of the shell to that appropriate for the contents
77  		initializeBounds();
78  	}
79  
80  
81  	protected final Shell createShell() 
82  	{
83  		Shell newShell = new Shell(parentShell, shellStyle);
84  
85  		resizeListener = new Listener() {
86  			public void handleEvent(Event e) {
87  				resizeHasOccurred = true;
88  			}
89  		};
90  	
91  		newShell.addListener(SWT.Resize,resizeListener);
92  		newShell.setData(this);
93  
94  		newShell.addShellListener(getShellListener());
95  
96  		configureShell(newShell);
97  		
98  		return newShell;
99  	}
100 	
101 	
102 	protected void configureShell(Shell newShell) 
103 	{
104 		GridLayout layout = new GridLayout();
105 		layout.marginHeight = 0;
106 		layout.marginWidth = 0;
107 		newShell.setLayout(layout);
108 	}
109 
110 
111 	protected Control createContents(Composite parent) 
112 	{
113 		Composite composite = new Composite(parent, 0);
114 		GridLayout layout = new GridLayout();
115 		layout.marginHeight = 0;
116 		layout.marginWidth = 0;
117 		layout.verticalSpacing = 0;
118 		composite.setLayout(layout);
119 		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
120 		composite.setFont(parent.getFont());
121 
122 		dialogArea = createDialogArea(composite);
123 		buttonBar = createButtonBar(composite);
124 
125 		return composite;
126 	}
127 
128 
129 	protected Control createDialogArea(Composite parent) 
130 	{
131 		Composite composite = new Composite(parent, SWT.NONE);
132 		
133 		composite.setLayout(new GridLayout());
134 		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
135 		composite.setFont(parent.getFont());
136 
137 		return composite;
138 	}
139 	
140 
141 	protected Control createButtonBar(Composite parent) 
142 	{
143 		Composite composite = new Composite(parent, SWT.NONE);
144 		
145 		composite.setLayout(new GridLayout(2, false));
146 		composite.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
147 		composite.setFont(parent.getFont());
148 
149 		btOk = new Button(composite, SWT.PUSH);
150 		btOk.setText("OK");		
151 		btOk.addSelectionListener(new SelectionAdapter() 
152 		{
153 			public void widgetSelected(SelectionEvent event) 
154 			{
155 				buttonPressed(OK);
156 			}
157 		});
158 		
159 		btCancel = new Button(composite, SWT.PUSH);
160 		btCancel.setText("Cancel");		
161 		btCancel.addSelectionListener(new SelectionAdapter() 
162 		{
163 			public void widgetSelected(SelectionEvent event) 
164 			{
165 				buttonPressed(CANCEL);
166 			}
167 		});
168 
169 		return composite;
170 	}
171 	
172 
173 	protected void initializeBounds() 
174 	{
175 		if (resizeListener != null) {
176 			shell.removeListener(SWT.Resize,resizeListener);
177 		}
178 	
179 		if (resizeHasOccurred) { // Check if shell size has been set already.
180 			return;
181 		}
182 
183 		Point size = getInitialSize();
184 		Point location = getInitialLocation(size);
185 
186 		shell.setBounds(location.x, location.y, size.x, size.y);
187 	}
188 	
189 	
190 	protected Point getInitialSize() 
191 	{
192 		return shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
193 	}
194 
195 
196 	protected Point getInitialLocation(Point initialSize) 
197 	{
198 		Composite parentShell = shell.getParent();
199 		Rectangle containerBounds = (parentShell != null) ? parentShell.getBounds() : shell.getDisplay().getClientArea();
200 		int x = Math.max(0, containerBounds.x + (containerBounds.width - initialSize.x) / 2);
201 		int y = Math.max(0, containerBounds.y + (containerBounds.height - initialSize.y) / 3);
202 		return new Point(x, y);
203 	}
204 	
205 	
206 	protected void buttonPressed(int buttonId) 
207 	{
208 		if (buttonId == OK) {
209 			okPressed();
210 		} else if (buttonId == CANCEL) {
211 			cancelPressed();
212 		}
213 	}
214 
215 
216 	protected void okPressed() 
217 	{
218 		setReturnCode(OK);
219 		close();
220 	}
221 	
222 	
223 	protected void cancelPressed() {
224 		setReturnCode(CANCEL);
225 		close();
226 	}
227 	
228 	
229 	protected int getReturnCode() 
230 	{
231 		return returnCode;
232 	}
233 	
234 	
235 	protected void setReturnCode(int code) 
236 	{
237 		returnCode = code;
238 	}
239 	
240 	
241 	protected ShellListener getShellListener() 
242 	{
243 		return new ShellAdapter() 
244 		{
245 			public void shellClosed(ShellEvent event) 
246 			{
247 				event.doit= false;	// don't close now
248 				setReturnCode(CANCEL);
249 				close();
250 			}
251 		};
252 	}
253 
254 
255 	public boolean close() 
256 	{
257 		if (shell != null || !shell.isDisposed()) {
258 			shell.dispose();
259 			shell = null;
260 			contents = null;
261 		}
262 
263 		buttonBar = null;
264 		dialogArea = null;
265 
266 		return true;
267 	}
268 
269 
270 	public Shell getShell() 
271 	{
272 		return shell;
273 	}
274 
275 
276 	public int open() 
277 	{
278 
279 		if (shell == null) {
280 			create();
281 		}
282 
283 		shell.open();
284 
285 		if (block) { 
286 			runEventLoop(shell);
287 		}	
288 
289 		return returnCode;
290 	}
291 
292 
293 	private void runEventLoop(Shell shell) 
294 	{
295 		Display display;
296 		if(shell == null) {
297 			 display = Display.getCurrent();
298 		}	else {
299 			display = shell.getDisplay();
300 		}
301 		
302 		while (shell != null && ! shell.isDisposed()) {
303 			try {
304 				if (!display.readAndDispatch()) {
305 					display.sleep();
306 				}
307 			} catch (Throwable ex) {
308 				System.err.println(ex);
309 			}
310 		}
311 		display.update();
312 	}
313 
314 }
315