View Javadoc

1   /**
2    *  MicroEmulator
3    *  Copyright (C) 2001-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;
21  
22  import java.io.File;
23  import java.io.IOException;
24  import java.net.MalformedURLException;
25  import java.net.URL;
26  import java.util.ArrayList;
27  import java.util.List;
28  
29  import org.eclipse.swt.SWT;
30  import org.eclipse.swt.events.KeyEvent;
31  import org.eclipse.swt.events.KeyListener;
32  import org.eclipse.swt.layout.GridData;
33  import org.eclipse.swt.layout.GridLayout;
34  import org.eclipse.swt.widgets.Display;
35  import org.eclipse.swt.widgets.Event;
36  import org.eclipse.swt.widgets.FileDialog;
37  import org.eclipse.swt.widgets.Label;
38  import org.eclipse.swt.widgets.Listener;
39  import org.eclipse.swt.widgets.Menu;
40  import org.eclipse.swt.widgets.MenuItem;
41  import org.eclipse.swt.widgets.Shell;
42  import org.microemu.DisplayComponent;
43  import org.microemu.EmulatorContext;
44  import org.microemu.MIDletBridge;
45  import org.microemu.app.ui.Message;
46  import org.microemu.app.ui.ResponseInterfaceListener;
47  import org.microemu.app.ui.StatusBarListener;
48  import org.microemu.app.ui.swt.SwtDeviceComponent;
49  import org.microemu.app.ui.swt.SwtDialog;
50  import org.microemu.app.ui.swt.SwtErrorMessageDialogPanel;
51  import org.microemu.app.ui.swt.SwtInputDialog;
52  import org.microemu.app.ui.swt.SwtMessageDialog;
53  import org.microemu.app.ui.swt.SwtSelectDeviceDialog;
54  import org.microemu.app.util.DeviceEntry;
55  import org.microemu.app.util.IOUtils;
56  import org.microemu.device.Device;
57  import org.microemu.device.DeviceDisplay;
58  import org.microemu.device.DeviceFactory;
59  import org.microemu.device.FontManager;
60  import org.microemu.device.InputMethod;
61  import org.microemu.device.impl.DeviceImpl;
62  import org.microemu.device.impl.Rectangle;
63  import org.microemu.device.swt.SwtDeviceDisplay;
64  import org.microemu.device.swt.SwtFontManager;
65  import org.microemu.device.swt.SwtInputMethod;
66  
67  public class Swt extends Common
68  {
69  	public static Shell shell;
70  
71  	protected static SwtDeviceComponent devicePanel;
72  
73  	protected MenuItem menuOpenJADFile;
74  	protected MenuItem menuOpenJADURL;
75  
76  	private SwtSelectDeviceDialog selectDeviceDialog;
77  	private FileDialog fileDialog = null;
78  	private MenuItem menuSelectDevice;
79  	    
80  	private DeviceEntry deviceEntry;
81  
82  	private Label statusBar;
83    
84  	private KeyListener keyListener = new KeyListener()
85  	{    
86  		public void keyTyped(KeyEvent e)
87  		{
88  		}
89      
90  		public void keyPressed(KeyEvent e)
91  		{
92  //			devicePanel.keyPressed(e);
93  		}
94      
95  		public void keyReleased(KeyEvent e)
96  		{
97  //			devicePanel.keyReleased(e);
98  		}    
99  	};
100    
101 	protected Listener menuOpenJADFileListener = new Listener()
102 	{
103 		public void handleEvent(Event ev)
104 		{
105 			if (fileDialog == null) {
106 				fileDialog = new FileDialog(shell, SWT.OPEN);
107 				fileDialog.setText("Open JAD File...");
108 				fileDialog.setFilterNames(new String[] {"JAD files"});
109 				fileDialog.setFilterExtensions(new String[] {"*.jad"});
110 				fileDialog.setFilterPath(Config.getRecentDirectory("recentJadDirectory"));
111 			}
112       
113 			fileDialog.open();
114 
115 			if (fileDialog.getFileName().length() > 0) {
116 				File selectedFile;
117 				if (fileDialog.getFilterPath() == null) {
118 					selectedFile = new File(fileDialog.getFileName());
119 				} else {
120 					selectedFile = new File(fileDialog.getFilterPath(), fileDialog.getFileName());
121 					Config.setRecentDirectory("recentJadDirectory", fileDialog.getFilterPath());
122 				}
123 				String url = IOUtils.getCanonicalFileURL(selectedFile);
124 				Common.openJadUrlSafe(url);
125 			}
126 		} 
127 	};
128   
129 	protected Listener menuOpenJADURLListener = new Listener()
130 	{
131 		public void handleEvent(Event ev)
132 		{
133 			// TODO change to JadUrlPanel
134 			SwtInputDialog inputDialog = new SwtInputDialog(shell, "Open...", "Enter JAD URL:");
135 			if (inputDialog.open() == SwtDialog.OK) {
136 				try {
137 					openJadUrl(inputDialog.getValue());
138 				} catch (IOException ex) {
139 					System.err.println("Cannot load " + inputDialog.getValue());
140 				}
141 			}
142 		}    
143 	};
144   
145 	protected Listener menuExitListener = new Listener()
146 	{    
147 		public void handleEvent(Event e)
148 		{
149 			Config.setWindow("main", new Rectangle(
150 			    	shell.getLocation().x,
151 			    	shell.getLocation().y,
152 			    	shell.getSize().x,
153 			    	shell.getSize().y));
154 
155 			System.exit(0);
156 		}    
157 	};
158   
159   
160 	private Listener menuSelectDeviceListener = new Listener()
161 	{    
162 		public void handleEvent(Event e)
163 		{
164 			if (selectDeviceDialog.open() == SwtDialog.OK) {
165 				if (selectDeviceDialog.getSelectedDeviceEntry().equals(getDevice())) {
166 					return;
167 				}
168 				if (MIDletBridge.getCurrentMIDlet() != getLauncher()) {
169 					if (!SwtMessageDialog.openQuestion(shell,
170 							"Question?", "Changing device needs MIDlet to be restarted. All MIDlet data will be lost. Are you sure?")) { 
171 						return;
172 					}
173 				}
174 				setDevice(selectDeviceDialog.getSelectedDeviceEntry());
175 
176 				if (MIDletBridge.getCurrentMIDlet() != getLauncher()) {
177 					try {
178 						startMidlet(MIDletBridge.getCurrentMIDlet().getClass(), MIDletBridge.getMIDletAccess());
179 					} catch (Exception ex) {
180 						System.err.println(ex);
181 					}
182 				} else {
183 					startLauncher(MIDletBridge.getMIDletContext());
184 				}
185 			}
186 		}    
187 	};
188 	
189 	private StatusBarListener statusBarListener = new StatusBarListener()
190 	{			
191 		public void statusBarChanged(final String text) 
192 		{			
193 			shell.getDisplay().asyncExec(new Runnable()
194 			{
195 				public void run() 
196 				{
197 					statusBar.setText(text);
198 				}
199 			});
200 		}  
201 	};
202   
203 	private ResponseInterfaceListener responseInterfaceListener = new ResponseInterfaceListener()
204 	{
205 		public void stateChanged(final boolean state) 
206 		{
207 			shell.getDisplay().asyncExec(new Runnable()
208 			{
209 				public void run() 
210 				{
211 					menuOpenJADFile.setEnabled(state);
212 					menuOpenJADURL.setEnabled(state);
213 					menuSelectDevice.setEnabled(state);
214 				}
215 			});
216 		}  
217 	};
218   
219 /*	WindowAdapter windowListener = new WindowAdapter()
220 	{
221 		public void windowClosing(WindowEvent ev) 
222 		{
223 			menuExitListener.actionPerformed(null);
224 		}
225 		
226 
227 		public void windowIconified(WindowEvent ev) 
228 		{
229 			MIDletBridge.getMIDletAccess(common.getLauncher().getCurrentMIDlet()).pauseApp();
230 		}
231 		
232 		public void windowDeiconified(WindowEvent ev) 
233 		{
234 			try {
235 				MIDletBridge.getMIDletAccess(common.getLauncher().getCurrentMIDlet()).startApp();
236 			} catch (MIDletStateChangeException ex) {
237 				System.err.println(ex);
238 			}
239 		}
240 	};*/
241 	
242 	protected Swt(Shell shell)
243 	{
244 		this(shell, null);
245 	}
246   
247 	protected Swt(Shell shell, DeviceEntry defaultDevice)
248 	{
249 		super(new EmulatorContext()
250 		{
251 			private InputMethod inputMethod = new SwtInputMethod();
252 			
253 			private DeviceDisplay deviceDisplay = new SwtDeviceDisplay(this);
254 
255 			private FontManager fontManager = new SwtFontManager();
256 			    
257 			public DisplayComponent getDisplayComponent()
258 			{
259 				return devicePanel.getDisplayComponent();
260 			}
261 
262             public InputMethod getDeviceInputMethod()
263             {
264                 return inputMethod;
265             }    
266 
267             public DeviceDisplay getDeviceDisplay()
268             {
269                 return deviceDisplay;
270             }
271 
272 			public FontManager getDeviceFontManager() 
273 			{
274 				return fontManager;
275 			}    
276 		});
277 
278 		initInterface(shell);
279 
280 //		addWindowListener(windowListener);
281 		    
282 		Config.loadConfig(null, emulatorContext);
283 		
284 		Rectangle window = Config.getWindow("main", new Rectangle(0, 0, 160, 120));
285 		shell.setLocation(window.x, window.y);
286 		
287 		shell.addKeyListener(keyListener);
288 
289 		selectDeviceDialog = new SwtSelectDeviceDialog(shell, emulatorContext);
290     
291 		setStatusBarListener(statusBarListener);
292 		setResponseInterfaceListener(responseInterfaceListener);
293 		
294 	    Message.addListener(new SwtErrorMessageDialogPanel(shell));
295 	}
296 	
297 	
298 	protected void initInterface(Shell shell)
299 	{
300 		GridLayout layout = new GridLayout(1, false);
301 		shell.setLayout(layout);
302 		shell.setLayoutData(new GridData(GridData.FILL_BOTH));
303 
304 		Menu bar = new Menu(shell, SWT.BAR);
305 		shell.setMenuBar(bar);
306     
307 		MenuItem menuFile = new MenuItem(bar, SWT.CASCADE);
308 		menuFile.setText("File");
309     
310 		Menu fileSubmenu = new Menu(shell, SWT.DROP_DOWN);
311 		menuFile.setMenu(fileSubmenu);
312 
313 		menuOpenJADFile = new MenuItem(fileSubmenu, SWT.PUSH);
314 		menuOpenJADFile.setText("Open JAD File...");
315 		menuOpenJADFile.addListener(SWT.Selection, menuOpenJADFileListener);
316 
317 		menuOpenJADURL = new MenuItem(fileSubmenu, 0);
318 		menuOpenJADURL.setText("Open JAD URL...");
319 		menuOpenJADURL.addListener(SWT.Selection, menuOpenJADURLListener);
320 
321 		new MenuItem(fileSubmenu, SWT.SEPARATOR);
322     
323 		MenuItem menuExit = new MenuItem(fileSubmenu, SWT.PUSH);
324 		menuExit.setText("Exit");
325 		menuExit.addListener(SWT.Selection, menuExitListener);
326     
327 		MenuItem menuOptions = new MenuItem(bar, SWT.CASCADE);
328 		menuOptions.setText("Options");
329     
330 		Menu optionsSubmenu = new Menu(shell, SWT.DROP_DOWN);
331 		menuOptions.setMenu(optionsSubmenu);
332 
333 		menuSelectDevice = new MenuItem(optionsSubmenu, SWT.PUSH);
334 		menuSelectDevice.setText("Select device...");
335 		menuSelectDevice.addListener(SWT.Selection, menuSelectDeviceListener);
336 
337 		shell.setText("MicroEmulator");
338 
339 		devicePanel = new SwtDeviceComponent(shell);
340 		devicePanel.setLayoutData(new GridData(GridData.FILL_BOTH));
341 
342 		statusBar = new Label(shell, SWT.HORIZONTAL);
343 		statusBar.setText("Status");
344 		statusBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
345 	}
346       
347   
348 	public void setDevice(DeviceEntry entry)
349 	{
350 		if (DeviceFactory.getDevice() != null) {
351 //			((SwtDevice) DeviceFactory.getDevice()).dispose();
352 		}
353 		
354 		try {
355 			ClassLoader classLoader = getClass().getClassLoader();
356 			if (entry.getFileName() != null) {
357 				URL[] urls = new URL[1];
358 				urls[0] = new File(Config.getConfigPath(), entry.getFileName()).toURI().toURL();
359 				classLoader = Common.createExtensionsClassLoader(urls);
360 			}
361 
362 			// TODO font manager have to be moved from emulatorContext into device
363 			emulatorContext.getDeviceFontManager().init();		
364 			
365 			Device device = DeviceImpl.create(
366 					emulatorContext, 
367 					classLoader, 
368 					entry.getDescriptorLocation());
369 			this.deviceEntry = entry;
370 			setDevice(device);
371 			updateDevice();
372 		} catch (MalformedURLException ex) {
373 			System.err.println(ex);
374 		} catch (IOException ex) {
375 			System.err.println(ex);
376 		}
377 	}
378 	
379 	
380 	protected void updateDevice()
381 	{
382 		shell.setSize(shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true));
383 	}
384   
385   
386 	public static void main(String args[])
387 	{
388 		Display display = new Display();
389 		shell = new Shell(display, SWT.CLOSE | SWT.TITLE | SWT.MIN);
390 		    
391 		List params = new ArrayList();
392 		for (int i = 0; i < args.length; i++) {
393 			params.add(args[i]);
394 		}
395 
396 		Swt app = new Swt(shell);
397 		app.initDevice(params, app.selectDeviceDialog.getSelectedDeviceEntry());
398 		app.updateDevice();
399 		
400 		shell.pack();
401 		shell.open();
402 		
403 		app.initMIDlet(params, false);
404 		
405 		while (!shell.isDisposed ()) {
406 			if (!display.readAndDispatch ())
407 				display.sleep ();
408 		}
409 		display.dispose();			
410 	}
411 
412 }