source: trunk/src/org/expeditee/gui/Browser.java@ 233

Last change on this file since 233 was 233, checked in by ra33, 16 years ago

Added MailFrame agent

File size: 11.7 KB
Line 
1package org.expeditee.gui;
2
3import java.awt.Color;
4import java.awt.Dimension;
5import java.awt.Graphics;
6import java.awt.Graphics2D;
7import java.awt.MouseInfo;
8import java.awt.Point;
9import java.awt.RenderingHints;
10import java.awt.Toolkit;
11import java.awt.event.ComponentEvent;
12import java.awt.event.ComponentListener;
13import java.awt.event.WindowEvent;
14import java.awt.event.WindowListener;
15import java.awt.event.WindowStateListener;
16import java.util.Collection;
17
18import javax.swing.JFrame;
19import javax.swing.RepaintManager;
20import javax.swing.SwingUtilities;
21
22import org.expeditee.AbsoluteLayout;
23import org.expeditee.FrameDNDTransferHandler;
24import org.expeditee.actions.Actions;
25import org.expeditee.actions.Simple;
26import org.expeditee.io.Logger;
27import org.expeditee.items.widgets.WidgetCacheManager;
28import org.expeditee.stats.StatsLogger;
29import org.expeditee.taskmanagement.EntitySaveManager;
30import org.expeditee.taskmanagement.SaveStateChangedEvent;
31import org.expeditee.taskmanagement.SaveStateChangedEventListener;
32
33/**
34 * The Main GUI class, comprises what people will see on the screen.<br>
35 * Note: Each Object (Item) is responsible for drawing itself on the screen.<br>
36 * Note2: The Frame is registered as a MouseListener and KeyListener, and
37 * processes any Events.
38 *
39 * @author jdm18
40 *
41 */
42public class Browser extends JFrame implements ComponentListener,
43 WindowListener, WindowStateListener, SaveStateChangedEventListener {
44
45 /**
46 * Default version - just to stop eclipse from complaining about it.
47 */
48 private static final long serialVersionUID = 1L;
49
50 // private static final JScrollPane scrollPane = new JScrollPane();
51
52 public static Browser _theBrowser = null;
53
54 // A flag which is set once the application is exiting.
55 private boolean _isExiting = false;
56
57 private static boolean _initComplete = false;
58
59 /**
60 * Constructs a new Browser object, then launches it
61 *
62 * @param args
63 */
64 public static void main(String[] args) {
65
66 // Prepare all expeditee and swing data on the AWT event thread.
67 SwingUtilities.invokeLater(new Runnable() {
68 public void run() {
69 // MessageBay.supressMessages(true);
70
71 // MessageBay.supressMessages(false);
72
73 _theBrowser = new Browser();
74 _theBrowser.requestFocus();
75 FrameMouseActions.MouseX = MouseInfo.getPointerInfo()
76 .getLocation().x
77 - _theBrowser.getOrigin().x;
78 FrameMouseActions.MouseY = MouseInfo.getPointerInfo()
79 .getLocation().y
80 - _theBrowser.getOrigin().y;
81 _initComplete = true;
82 }
83 });
84
85 }
86
87 public Point getOrigin() {
88 return getContentPane().getLocationOnScreen();
89 }
90
91 /**
92 * @return
93 *
94 * True if the application is about to exit. False if not. Not that this is
95 * only set once the window is in its closed state (not closing) or if the
96 * application has explicity being requested to exit.
97 *
98 * @see Browser#exit()
99 *
100 */
101 public boolean isExisting() {
102 return _isExiting;
103 }
104
105 private static boolean isInitComplete() {
106 return _initComplete;
107 }
108
109 public void setSizes(Dimension size) {
110 setSize(size);
111 setPreferredSize(size);
112 Dimension paneSize = getContentPane().getSize();
113 FrameGraphics.setMaxSize(paneSize);
114 }
115
116 private Browser() {
117 // Use the default values initially so we can load the profile frame
118 setSizes(new Dimension(UserSettings.InitialWidth,
119 UserSettings.InitialHeight));
120 // center the frame on the screen
121 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
122 double xpos = screen.getWidth() / 2;
123 double ypos = screen.getHeight() / 2;
124 setLocation((int) (xpos - (UserSettings.InitialWidth / 2)),
125 (int) (ypos - (UserSettings.InitialHeight / 2)));
126
127 addWindowListener(this);
128 addWindowStateListener(this);
129
130 DisplayIO.addDisplayIOObserver(WidgetCacheManager.getInstance());
131 DisplayIO.addDisplayIOObserver(PopupManager.getInstance());
132
133 UserSettings.Init();
134 UserSettings.Username = FrameIO.ConvertToValidFramesetName(System
135 .getProperty("user.name"));
136 String userName = UserSettings.Username;
137 Frame profile = FrameIO.LoadProfile(userName);
138 if (profile == null) {
139 try {
140 profile = FrameIO.CreateNewProfile(userName);
141 } catch (Exception e) {
142 // TODO tell the user that there was a problem creating the
143 // profile frame and close nicely
144 e.printStackTrace();
145 assert (false);
146 }
147 }
148
149 // Need to display errors once things have been init otherwise
150 // exceptions occur if there are more than four messages neededing to be
151 // displayed.
152 Collection<String> warningMessages = FrameUtils.ParseProfile(profile);
153
154 // set the layout to absolute layout for widgets
155 this.getContentPane().setLayout(new AbsoluteLayout());
156 // enable the glasspane-for capturing all mouse events
157 this
158 .setGlassPane(new MouseEventRouter(getJMenuBar(),
159 getContentPane()));
160 this.getGlassPane().setVisible(true);
161 this.getContentPane().setBackground(Color.white);
162 this.getContentPane().setFocusTraversalKeysEnabled(false);
163
164 addComponentListener(this);
165 pack();
166
167 // Reset windows to user specified size
168 // Must be done after initialising the content pane above!
169 setSizes(new Dimension(UserSettings.InitialWidth,
170 UserSettings.InitialHeight));
171
172 // See java bug ID 4016934. They say that window closed events are
173 // called once the
174 // jframe is disposed.
175 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
176
177 // Expeditee handles its own repainting of AWT/Swing components
178 RepaintManager.setCurrentManager(ExpediteeRepaintManager.getInstance());
179
180 // Listen for save status to display during and after runtime
181 EntitySaveManager.getInstance().addSaveStateChangedEventListener(this);
182
183 String version = System.getProperty("java.version");
184
185 if (version.startsWith("1.6")) {
186 // Set the drag and drop handler
187 setTransferHandler(FrameDNDTransferHandler.getInstance());
188 } else {
189 System.out.println("Upgrade to Java 1.6 to enable drag and drop");
190 }
191
192 try {
193 warningMessages.addAll(Actions.Init());
194
195 DisplayIO.Init(this);
196 // Set visible must be just after DisplayIO.Init for the message box
197 // to
198 // be the right size
199 setVisible(true);
200
201 setupGraphics();
202
203 // required to accept TAB key
204 setFocusTraversalKeysEnabled(false);
205
206 // Must be loaded after setupGraphics if images are on the frame
207 // Turn off XRay mode and load the first frame
208 FrameUtils.loadFirstFrame(profile);
209 FrameGraphics.setMode(FrameGraphics.MODE_NORMAL, false);
210 DisplayIO.UpdateTitle();
211
212 // I think this can be moved back up to the top of the Go method
213 // now...
214 // It used to crash the program trying to print error messages up
215 // the top
216 for (String message : warningMessages)
217 MessageBay.warningMessage(message);
218
219 FrameKeyboardActions keyboardListner = new FrameKeyboardActions();
220 this.getContentPane().addKeyListener(keyboardListner);
221 this.addKeyListener(keyboardListner);
222
223 FrameKeyboardActions.Refresh();
224 // setVisible(true);
225 } catch (Exception e) {
226 e.printStackTrace();
227 Logger.Log(e);
228 }
229 }
230
231 public Graphics2D g;
232
233 private void setupGraphics() {
234 if (g != null)
235 g.dispose();
236 g = (Graphics2D) this.getContentPane().getGraphics();
237 assert (g != null);
238 g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
239 RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
240 g.setFont(g.getFont().deriveFont(40f));
241 FrameGraphics.setDisplayGraphics(g);
242 }
243
244 // private int count = 0;
245 @Override
246 public void paint(Graphics g) {
247 // All this does is make sure the screen is repainted when the browser
248 // is moved so that some of the window is off the edge of the display
249 // then moved back into view
250 super.paint(g);
251 FrameGraphics.ForceRepaint();
252 // System.out.println("Paint " + count++);
253 }
254
255 /**
256 * @inheritDoc
257 */
258 public void componentResized(ComponentEvent e) {
259 setSizes(this.getSize());
260 setupGraphics();
261 FrameIO.RefreshCasheImages();
262 FrameGraphics.ForceRepaint();
263 }
264
265 /**
266 * @inheritDoc
267 */
268 public void componentMoved(ComponentEvent e) {
269 // FrameGraphics.setMaxSize(this.getSize());
270 }
271
272 /**
273 * @inheritDoc
274 */
275 public void componentShown(ComponentEvent e) {
276 }
277
278 /**
279 * @inheritDoc
280 */
281 public void componentHidden(ComponentEvent e) {
282 }
283
284 public void windowClosing(WindowEvent e) {
285 }
286
287 public void windowClosed(WindowEvent e) {
288 exit();
289 }
290
291 public void windowOpened(WindowEvent e) {
292 }
293
294 public void windowIconified(WindowEvent e) {
295 }
296
297 public void windowDeiconified(WindowEvent e) {
298 }
299
300 public void windowActivated(WindowEvent e) {
301 // System.out.println("Activated");
302 }
303
304 public void windowDeactivated(WindowEvent e) {
305 }
306
307 public void windowStateChanged(WindowEvent e) {
308 }
309
310 public int getDrawingAreaX() {
311 // return scrollPane.getLocationOnScreen().x;
312 return this.getLocationOnScreen().x;
313 }
314
315 public int getDrawingAreaY() {
316 // return scrollPane.getLocationOnScreen().y;
317 return this.getLocationOnScreen().y;
318 }
319
320 public void saveCompleted(SaveStateChangedEvent event) {
321 // if (isExisting()) {
322
323 // } else {
324 MessageBay.displayMessage("Save finished!", Color.BLUE);
325 // }
326 }
327
328 public void saveStarted(SaveStateChangedEvent event) {
329 // if (isExisting()) {
330
331 // } else {
332 String name = event.getEntity().getSaveName();
333 if (name == null)
334 name = "data";
335 MessageBay.displayMessage("Saving " + name + "...", Color.BLUE);
336 // }
337 }
338
339 /**
340 * Closes the browser and ends the application. Performs saving operations -
341 * halting until saves have completed. Feedback is given to the user while
342 * the application is exiting. Must call on the swing thread.
343 */
344 public void exit() {
345
346 // Set exiting flag
347 _isExiting = true;
348
349 MessageBay.displayMessage("System exiting...");
350
351 /**
352 * TODO: Prompt the user etc.
353 */
354
355 // TODO: Should we should a popup with a progress bar for user feedback?
356 // this would be nice and easy to do.
357 // Exit on a dedicated thread so that feedback can be obtained
358 new Exiter().start(); // this will exit the application
359 }
360
361 /**
362 * The system must exit on a different thread other than the swing thread so
363 * that the save threads can fire save-feedback to the swing thread and thus
364 * provide user feedback on asynchronous save operations.
365 *
366 * @author Brook Novak
367 *
368 */
369 private class Exiter extends Thread {
370
371 @Override
372 public void run() {
373
374 // The final save point for saveable entities
375 EntitySaveManager.getInstance().saveAll();
376 try {
377 EntitySaveManager.getInstance().waitUntilAllSavingFinished();
378 } catch (InterruptedException e) {
379 e.printStackTrace();
380 }
381
382 // The final phase must save on the wing thread since dealing with
383 // the expeditee
384 // data model
385 SwingUtilities.invokeLater(new Runnable() {
386 public void run() {
387
388 // Stop any agents or simple programs
389 Simple.stop();
390 Actions.stopAgent();
391 // Wait for them to stop
392 try {
393 MessageBay
394 .displayMessage("Stopping Simple programs..."); // TODO:
395 // Only
396 // stop
397 // if
398 // need
399 // to...
400 while (Simple.isProgramRunning()) {
401 Thread.sleep(100); // Brook: What purpose does this
402 // serve?
403 }
404 MessageBay.displayMessage("Stopping Agents..."); // TODO:
405 // Only
406 // stop
407 // if
408 // need
409 // to...
410 while (Actions.isAgentRunning()) {
411 Thread.sleep(100); // Brook: What purpose does this
412 // serve?
413 }
414 } catch (Exception e) {
415
416 }
417
418 MessageBay.displayMessage("Saving current frame...");
419 FrameIO.SaveFrame(DisplayIO.getCurrentFrame());
420
421 while (FrameIO.DeleteFrameset("messages"))
422 ;
423
424 MessageBay.displayMessage("Saving stats...");
425 StatsLogger.WriteStatsFile();
426
427 MessageBay.displayMessage("System exited");
428 System.exit(0);
429
430 }
431 });
432
433 }
434
435 }
436
437 public static Browser initialize() {
438 if (Browser._theBrowser == null) {
439 Browser.main(null);
440 try {
441 while (!isInitComplete()) {
442 Thread.sleep(10);
443 }
444 } catch (Exception e) {
445 }
446 }
447 return _theBrowser;
448 }
449
450}
Note: See TracBrowser for help on using the repository browser.