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

Last change on this file since 171 was 171, checked in by bjn8, 16 years ago

Removed java 1.6 reliant method for DnD. Now only requires 1.5

File size: 11.3 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.JComponent;
19import javax.swing.JFrame;
20import javax.swing.RepaintManager;
21import javax.swing.SwingUtilities;
22
23import org.expeditee.AbsoluteLayout;
24import org.expeditee.FrameDNDTransferHandler;
25import org.expeditee.actions.Actions;
26import org.expeditee.actions.Simple;
27import org.expeditee.io.Logger;
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 UserSettings.Init();
131 UserSettings.Username = FrameIO.ConvertToValidFramesetName(System
132 .getProperty("user.name"));
133 String userName = UserSettings.Username;
134 Frame profile = FrameIO.LoadProfile(userName);
135 if (profile == null) {
136 try {
137 profile = FrameIO.CreateNewProfile(userName);
138 } catch (Exception e) {
139 // TODO tell the user that there was a problem creating the
140 // profile frame and close nicely
141 e.printStackTrace();
142 assert (false);
143 }
144 }
145
146 FrameUtils.ParseProfile(profile);
147
148 // set the layout to absolute layout for widgets
149 this.getContentPane().setLayout(new AbsoluteLayout());
150 // enable the glasspane-for capturing all mouse events
151 this
152 .setGlassPane(new MouseEventRouter(getJMenuBar(),
153 getContentPane()));
154 this.getGlassPane().setVisible(true);
155 this.getContentPane().setBackground(Color.white);
156 this.getContentPane().setFocusTraversalKeysEnabled(false);
157
158 addComponentListener(this);
159 pack();
160
161 // Reset windows to user specified size
162 // Must be done after initialising the content pane above!
163 setSizes(new Dimension(UserSettings.InitialWidth,
164 UserSettings.InitialHeight));
165
166 // See java bug ID 4016934. They say that window closed events are
167 // called once the
168 // jframe is disposed.
169 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
170
171 // Expeditee handles its own repainting of AWT/Swing components
172 RepaintManager.setCurrentManager(ExpediteeRepaintManager.getInstance());
173
174 // Listen for save status to display during and after runtime
175 EntitySaveManager.getInstance().addSaveStateChangedEventListener(this);
176
177 if (getContentPane() instanceof JComponent) {
178 ((JComponent)getContentPane()).setTransferHandler(FrameDNDTransferHandler.getInstance());
179 }
180
181 try {
182 Collection<String> warningMessages = Actions.Init();
183
184 DisplayIO.Init(this);
185 // Set visible must be just after DisplayIO.Init for the message box
186 // to
187 // be the right size
188 setVisible(true);
189
190 setupGraphics();
191
192 // required to accept TAB key
193 setFocusTraversalKeysEnabled(false);
194
195 // Must be loaded after setupGraphics if images are on the frame
196 // Turn off XRay mode and load the first frame
197 FrameUtils.loadFirstFrame(profile);
198 FrameGraphics.setMode(FrameGraphics.MODE_NORMAL, false);
199 DisplayIO.UpdateTitle();
200
201 // I think this can be moved back up to the top of the Go method
202 // now...
203 // It used to crash the program trying to print error messages up
204 // the top
205 for (String message : warningMessages)
206 MessageBay.warningMessage(message);
207
208 FrameKeyboardActions keyboardListner = new FrameKeyboardActions();
209 this.getContentPane().addKeyListener(keyboardListner);
210 this.addKeyListener(keyboardListner);
211
212 FrameKeyboardActions.Refresh();
213 // setVisible(true);
214 } catch (Exception e) {
215 e.printStackTrace();
216 Logger.Log(e);
217 }
218 }
219
220 public Graphics2D g;
221
222 private void setupGraphics() {
223 if (g != null)
224 g.dispose();
225 g = (Graphics2D) this.getContentPane().getGraphics();
226 assert (g != null);
227 g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
228 RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
229 g.setFont(g.getFont().deriveFont(40f));
230 FrameGraphics.setDisplayGraphics(g);
231 }
232
233 // private int count = 0;
234 @Override
235 public void paint(Graphics g) {
236 // All this does is make sure the screen is repainted when the browser
237 // is moved so that some of the window is off the edge of the display
238 // then moved back into view
239 super.paint(g);
240 FrameGraphics.ForceRepaint();
241 // System.out.println("Paint " + count++);
242 }
243
244 /**
245 * @inheritDoc
246 */
247 public void componentResized(ComponentEvent e) {
248 setSizes(this.getSize());
249 setupGraphics();
250 FrameIO.RefreshCasheImages();
251 FrameGraphics.ForceRepaint();
252 }
253
254 /**
255 * @inheritDoc
256 */
257 public void componentMoved(ComponentEvent e) {
258 // FrameGraphics.setMaxSize(this.getSize());
259 }
260
261 /**
262 * @inheritDoc
263 */
264 public void componentShown(ComponentEvent e) {
265 }
266
267 /**
268 * @inheritDoc
269 */
270 public void componentHidden(ComponentEvent e) {
271 }
272
273 public void windowClosing(WindowEvent e) {
274 }
275
276 public void windowClosed(WindowEvent e) {
277 exit();
278 }
279
280 public void windowOpened(WindowEvent e) {
281 }
282
283 public void windowIconified(WindowEvent e) {
284 }
285
286 public void windowDeiconified(WindowEvent e) {
287 }
288
289 public void windowActivated(WindowEvent e) {
290 // System.out.println("Activated");
291 }
292
293 public void windowDeactivated(WindowEvent e) {
294 }
295
296 public void windowStateChanged(WindowEvent e) {
297 }
298
299 public int getDrawingAreaX() {
300 // return scrollPane.getLocationOnScreen().x;
301 return this.getLocationOnScreen().x;
302 }
303
304 public int getDrawingAreaY() {
305 // return scrollPane.getLocationOnScreen().y;
306 return this.getLocationOnScreen().y;
307 }
308
309 public void saveCompleted(SaveStateChangedEvent event) {
310 // if (isExisting()) {
311
312 // } else {
313 MessageBay.displayMessage("Save finished!", Color.BLUE);
314 // }
315 }
316
317 public void saveStarted(SaveStateChangedEvent event) {
318 // if (isExisting()) {
319
320 // } else {
321 String name = event.getEntity().getSaveName();
322 if (name == null)
323 name = "data";
324 MessageBay.displayMessage("Saving " + name + "...", Color.BLUE);
325 // }
326 }
327
328 /**
329 * Closes the browser and ends the application. Performs saving operations -
330 * halting until saves have completed. Feedback is given to the user while
331 * the application is exiting. Must call on the swing thread.
332 */
333 public void exit() {
334
335 // Set exiting flag
336 _isExiting = true;
337
338 MessageBay.displayMessage("System exiting...");
339
340 /**
341 * TODO: Prompt the user etc.
342 */
343
344 // TODO: Should we should a popup with a progress bar for user feedback?
345 // this would be nice and easy to do.
346 // Exit on a dedicated thread so that feedback can be obtained
347 new Exiter().start(); // this will exit the application
348 }
349
350 /**
351 * The system must exit on a different thread other than the swing thread so
352 * that the save threads can fire save-feedback to the swing thread and thus
353 * provide user feedback on asynchronous save operations.
354 *
355 * @author Brook Novak
356 *
357 */
358 private class Exiter extends Thread {
359
360 @Override
361 public void run() {
362
363 // The final save point for saveable entities
364 EntitySaveManager.getInstance().saveAll();
365 try {
366 EntitySaveManager.getInstance().waitUntilAllSavingFinished();
367 } catch (InterruptedException e) {
368 e.printStackTrace();
369 }
370
371 // The final phase must save on the wing thread since dealing with
372 // the expeditee
373 // data model
374 SwingUtilities.invokeLater(new Runnable() {
375 public void run() {
376
377 // Stop any agents or simple programs
378 Simple.stop();
379 Actions.stopAgent();
380 // Wait for them to stop
381 try {
382 MessageBay
383 .displayMessage("Stopping Simple programs..."); // TODO:
384 // Only
385 // stop
386 // if
387 // need
388 // to...
389 while (Simple.isProgramRunning()) {
390 Thread.sleep(100); // Brook: What purpose does this
391 // serve?
392 }
393 MessageBay.displayMessage("Stopping Agents..."); // TODO:
394 // Only
395 // stop
396 // if
397 // need
398 // to...
399 while (Actions.isAgentRunning()) {
400 Thread.sleep(100); // Brook: What purpose does this
401 // serve?
402 }
403 } catch (Exception e) {
404
405 }
406
407 MessageBay.displayMessage("Saving current frame...");
408 FrameIO.SaveFrame(DisplayIO.getCurrentFrame());
409
410 while (FrameIO.DeleteFrameset("messages"))
411 ;
412
413 MessageBay.displayMessage("Saving stats...");
414 StatsLogger.WriteStatsFile();
415
416 MessageBay.displayMessage("System exited");
417 System.exit(0);
418
419 }
420 });
421
422 }
423
424 }
425
426 public static Browser initialize(){
427 if (Browser._theBrowser == null) {
428 Browser.main(null);
429 try {
430 while (!isInitComplete()) {
431 Thread.sleep(10);
432 }
433 } catch (Exception e) {
434 }
435 }
436 return _theBrowser;
437 }
438
439}
Note: See TracBrowser for help on using the repository browser.