blob: 9f7aa63c43065cd421802c9a959df8f97c9a42ba [file] [log] [blame]
Constantin Kaplinsky1215b992008-04-18 09:51:44 +00001//
2// Copyright (C) 2001,2002 HorizonLive.com, Inc. All Rights Reserved.
3// Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
4//
5// This is free software; you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation; either version 2 of the License, or
8// (at your option) any later version.
9//
10// This software 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
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this software; if not, write to the Free Software
17// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
18// USA.
19//
20
wimba.comc23aeb02004-09-16 00:00:00 +000021package com.HorizonLive.RfbPlayer;
22
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000023import java.awt.*;
24import java.awt.event.*;
25import java.io.*;
Constantin Kaplinsky5d99c952002-05-25 09:49:23 +000026import java.net.*;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000027
Constantin Kaplinsky903009e2002-05-20 10:55:47 +000028public class RfbPlayer extends java.applet.Applet
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +000029 implements java.lang.Runnable, WindowListener {
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000030
31 boolean inAnApplet = true;
32 boolean inSeparateFrame = false;
33
wimba.com252eb3b2004-09-21 21:27:54 +000034 /** current applet width */
35 int dispW = 300;
36 /** current applet height */
37 int dispH = 200;
38
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000039 //
40 // main() is called when run as a java program from the command line.
41 // It simply runs the applet inside a newly-created frame.
42 //
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000043 public static void main(String[] argv) {
Constantin Kaplinsky903009e2002-05-20 10:55:47 +000044 RfbPlayer p = new RfbPlayer();
45 p.mainArgs = argv;
46 p.inAnApplet = false;
47 p.inSeparateFrame = true;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000048
Constantin Kaplinsky903009e2002-05-20 10:55:47 +000049 p.init();
50 p.start();
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000051 }
52
53 String[] mainArgs;
54
55 RfbProto rfb;
56 Thread rfbThread;
57
58 Frame vncFrame;
59 Container vncContainer;
wimba.come8e19102005-02-08 17:15:23 +000060 //ScrollPane desktopScrollPane;
61 LWScrollPane desktopScrollPane;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000062 GridBagLayout gridbag;
63 ButtonPanel buttonPanel;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000064 VncCanvas vc;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000065
Constantin Kaplinsky5d99c952002-05-25 09:49:23 +000066 String sessionURL;
Constantin Kaplinskyc833e012002-05-30 17:59:22 +000067 URL url;
Constantin Kaplinsky972c2572002-05-30 14:19:02 +000068 long initialTimeOffset;
Constantin Kaplinsky7957ca12002-05-30 16:19:11 +000069 double playbackSpeed;
Constantin Kaplinsky5a7133a2002-07-24 17:02:04 +000070 boolean autoPlay;
Constantin Kaplinsky903009e2002-05-20 10:55:47 +000071 boolean showControls;
wimba.comd1f56df2004-11-01 16:18:54 +000072 boolean isQuitting = false;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000073 int deferScreenUpdates;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000074
75 //
76 // init()
77 //
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000078 public void init() {
79
wimba.comc23aeb02004-09-16 00:00:00 +000080 // LiveConnect work-a-round
81 RfbSharedStatic.refApplet = this;
82
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000083 readParameters();
84
85 if (inSeparateFrame) {
Constantin Kaplinsky903009e2002-05-20 10:55:47 +000086 vncFrame = new Frame("RFB Session Player");
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000087 if (!inAnApplet) {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +000088 vncFrame.add("Center", this);
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000089 }
90 vncContainer = vncFrame;
91 } else {
92 vncContainer = this;
93 }
94
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000095 if (inSeparateFrame)
96 vncFrame.addWindowListener(this);
97
wimba.comd1f56df2004-11-01 16:18:54 +000098 rfbThread = new Thread(this, "RfbThread");
Constantin Kaplinsky1215b992008-04-18 09:51:44 +000099 rfbThread.start();
100 }
101
102 public void update(Graphics g) {
103 }
104
105 //
Constantin Kaplinsky903009e2002-05-20 10:55:47 +0000106 // run() - executed by the rfbThread to read RFB data.
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000107 //
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000108 public void run() {
109
110 gridbag = new GridBagLayout();
111 vncContainer.setLayout(gridbag);
112
113 GridBagConstraints gbc = new GridBagConstraints();
114 gbc.gridwidth = GridBagConstraints.REMAINDER;
115 gbc.anchor = GridBagConstraints.NORTHWEST;
116
Constantin Kaplinsky903009e2002-05-20 10:55:47 +0000117 if (showControls) {
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000118 buttonPanel = new ButtonPanel(this);
119 buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
120 gridbag.setConstraints(buttonPanel, gbc);
121 vncContainer.add(buttonPanel);
122 }
123
Constantin Kaplinsky903009e2002-05-20 10:55:47 +0000124 if (inSeparateFrame) {
125 vncFrame.pack();
126 vncFrame.show();
127 } else {
128 validate();
129 }
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000130
Constantin Kaplinsky903009e2002-05-20 10:55:47 +0000131 try {
Constantin Kaplinsky40ad1712002-09-22 08:36:43 +0000132 if (inAnApplet) {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000133 url = new URL(getCodeBase(), sessionURL);
Constantin Kaplinsky40ad1712002-09-22 08:36:43 +0000134 } else {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000135 url = new URL(sessionURL);
Constantin Kaplinsky40ad1712002-09-22 08:36:43 +0000136 }
Constantin Kaplinsky37cc43e2002-05-30 17:30:11 +0000137 rfb = new RfbProto(url);
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000138
139 vc = new VncCanvas(this);
140 gbc.weightx = 1.0;
141 gbc.weighty = 1.0;
142
wimba.com252eb3b2004-09-21 21:27:54 +0000143 // Create a panel which itself is resizeable and can hold
144 // non-resizeable VncCanvas component at the top left corner.
wimba.come8e19102005-02-08 17:15:23 +0000145 //Panel canvasPanel = new Panel();
146 //canvasPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
147 //canvasPanel.add(vc);
wimba.com252eb3b2004-09-21 21:27:54 +0000148
149 // Create a ScrollPane which will hold a panel with VncCanvas
150 // inside.
wimba.come8e19102005-02-08 17:15:23 +0000151 //desktopScrollPane = new ScrollPane(ScrollPane.SCROLLBARS_AS_NEEDED);
152 desktopScrollPane = new LWScrollPane();
wimba.com252eb3b2004-09-21 21:27:54 +0000153 gbc.fill = GridBagConstraints.BOTH;
wimba.come8e19102005-02-08 17:15:23 +0000154 gridbag.setConstraints(vc, gbc);
155 //gridbag.setConstraints(canvasPanel, gbc);
156 desktopScrollPane.addComp(vc);
157 desktopScrollPane.setSize(dispW, dispH);
158 //desktopScrollPane.add(canvasPanel);
wimba.com252eb3b2004-09-21 21:27:54 +0000159
160 // Now add the scroll bar to the container.
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000161 if (inSeparateFrame) {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000162 gridbag.setConstraints(desktopScrollPane, gbc);
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000163 vncFrame.add(desktopScrollPane);
164 vncFrame.setTitle(rfb.desktopName);
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000165 vc.resizeDesktopFrame();
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000166 } else {
wimba.com252eb3b2004-09-21 21:27:54 +0000167 // Size the scroll pane to display size.
168 desktopScrollPane.setSize(dispW, dispH);
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000169
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000170 // Just add the VncCanvas component to the Applet.
wimba.com252eb3b2004-09-21 21:27:54 +0000171 gbc.fill = GridBagConstraints.NONE;
172 gridbag.setConstraints(desktopScrollPane, gbc);
173 add(desktopScrollPane);
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000174 validate();
wimba.com252eb3b2004-09-21 21:27:54 +0000175 vc.resizeEmbeddedApplet();
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000176 }
177
wimba.comd1f56df2004-11-01 16:18:54 +0000178 while (!isQuitting) {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000179 try {
180 setPaused(!autoPlay);
181 rfb.fbs.setSpeed(playbackSpeed);
182 if (initialTimeOffset > rfb.fbs.getTimeOffset())
183 setPos(initialTimeOffset); // don't seek backwards here
184 vc.processNormalProtocol();
185 } catch (EOFException e) {
186 if (e.getMessage() != null && e.getMessage().equals("[REWIND]")) {
187 // A special type of EOFException allowing us to seek backwards.
188 initialTimeOffset = rfb.fbs.getSeekOffset();
189 autoPlay = !rfb.fbs.isPaused();
190 } else {
191 // Return to the beginning after the playback is finished.
192 initialTimeOffset = 0;
193 autoPlay = false;
194 }
Constantin Kaplinsky282aaa12002-09-22 11:33:22 +0000195 rfb.newSession(url);
196 vc.updateFramebufferSize();
wimba.com30ff9ed2004-11-01 20:54:08 +0000197 } catch (NullPointerException e) {
198 // catching this causes a hang with 1.4.1 JVM's under Win32 IE
199 throw e;
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000200 }
Constantin Kaplinsky903009e2002-05-20 10:55:47 +0000201 }
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000202
Constantin Kaplinsky903009e2002-05-20 10:55:47 +0000203 } catch (FileNotFoundException e) {
204 fatalError(e.toString());
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000205 } catch (Exception e) {
206 e.printStackTrace();
207 fatalError(e.toString());
208 }
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000209
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000210 }
211
Constantin Kaplinskyac6420d2002-05-29 17:05:39 +0000212 public void setPaused(boolean paused) {
Constantin Kaplinsky972c2572002-05-30 14:19:02 +0000213 if (showControls)
214 buttonPanel.setPaused(paused);
Constantin Kaplinsky37cc43e2002-05-30 17:30:11 +0000215 if (paused) {
216 rfb.fbs.pausePlayback();
217 } else {
218 rfb.fbs.resumePlayback();
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000219 }
220 }
221
Constantin Kaplinsky7957ca12002-05-30 16:19:11 +0000222 public double getSpeed() {
223 return playbackSpeed;
224 }
225
Constantin Kaplinskyce39d3b2002-05-30 15:54:56 +0000226 public void setSpeed(double speed) {
Constantin Kaplinsky7957ca12002-05-30 16:19:11 +0000227 playbackSpeed = speed;
Constantin Kaplinsky37cc43e2002-05-30 17:30:11 +0000228 rfb.fbs.setSpeed(speed);
Constantin Kaplinskyce39d3b2002-05-30 15:54:56 +0000229 }
230
wimba.comc23aeb02004-09-16 00:00:00 +0000231 public void jumpTo(long pos) {
232 long diff = Math.abs(pos - rfb.fbs.getTimeOffset());
233
234 // Current threshold is 5 seconds
235 if (diff > 5000) {
236 rfb.fbs.pausePlayback();
237 setPos(pos);
238 rfb.fbs.resumePlayback();
239 }
240 }
241
Constantin Kaplinskyc833e012002-05-30 17:59:22 +0000242 public void setPos(long pos) {
Constantin Kaplinsky5b1b92a2002-05-30 18:02:34 +0000243 rfb.fbs.setTimeOffset(pos);
Constantin Kaplinsky30f786a2002-05-29 10:59:52 +0000244 }
245
Constantin Kaplinskyfe079832002-05-29 00:52:32 +0000246 public void updatePos() {
Constantin Kaplinsky972c2572002-05-30 14:19:02 +0000247 if (showControls)
Constantin Kaplinskyc833e012002-05-30 17:59:22 +0000248 buttonPanel.setPos(rfb.fbs.getTimeOffset());
Constantin Kaplinskyfe079832002-05-29 00:52:32 +0000249 }
250
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000251 //
252 // readParameters() - read parameters from the html source or from the
253 // command line. On the command line, the arguments are just a sequence of
254 // param_name/param_value pairs where the names and values correspond to
255 // those expected in the html applet tag source.
256 //
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000257 public void readParameters() {
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000258
Constantin Kaplinsky5d99c952002-05-25 09:49:23 +0000259 sessionURL = readParameter("URL", true);
Constantin Kaplinsky5a7133a2002-07-24 17:02:04 +0000260
Constantin Kaplinsky972c2572002-05-30 14:19:02 +0000261 initialTimeOffset = readLongParameter("Position", 0);
Constantin Kaplinsky7957ca12002-05-30 16:19:11 +0000262 if (initialTimeOffset < 0)
263 initialTimeOffset = 0;
Constantin Kaplinsky5a7133a2002-07-24 17:02:04 +0000264
Constantin Kaplinsky7957ca12002-05-30 16:19:11 +0000265 playbackSpeed = readDoubleParameter("Speed", 1.0);
266 if (playbackSpeed <= 0.0)
267 playbackSpeed = 1.0;
Constantin Kaplinsky903009e2002-05-20 10:55:47 +0000268
Constantin Kaplinsky5a7133a2002-07-24 17:02:04 +0000269 autoPlay = false;
270 String str = readParameter("Autoplay", false);
271 if (str != null && str.equalsIgnoreCase("Yes"))
272 autoPlay = true;
273
Constantin Kaplinsky903009e2002-05-20 10:55:47 +0000274 showControls = true;
Constantin Kaplinsky5a7133a2002-07-24 17:02:04 +0000275 str = readParameter("Show Controls", false);
Constantin Kaplinsky903009e2002-05-20 10:55:47 +0000276 if (str != null && str.equalsIgnoreCase("No"))
277 showControls = false;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000278
279 if (inAnApplet) {
280 str = readParameter("Open New Window", false);
281 if (str != null && str.equalsIgnoreCase("Yes"))
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000282 inSeparateFrame = true;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000283 }
284
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000285 // Fine tuning options.
Constantin Kaplinsky972c2572002-05-30 14:19:02 +0000286 deferScreenUpdates = (int)readLongParameter("Defer screen updates", 20);
287 if (deferScreenUpdates < 0)
288 deferScreenUpdates = 0; // Just in case.
wimba.com252eb3b2004-09-21 21:27:54 +0000289
290 // Display width and height.
291 dispW = readIntParameter("DISPLAY_WIDTH", dispW);
292 dispH = readIntParameter("DISPLAY_HEIGHT", dispH);
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000293 }
294
295 public String readParameter(String name, boolean required) {
296 if (inAnApplet) {
297 String s = getParameter(name);
298 if ((s == null) && required) {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000299 fatalError(name + " parameter not specified");
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000300 }
301 return s;
302 }
303
304 for (int i = 0; i < mainArgs.length; i += 2) {
305 if (mainArgs[i].equalsIgnoreCase(name)) {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000306 try {
307 return mainArgs[i + 1];
308 } catch (Exception e) {
309 if (required) {
310 fatalError(name + " parameter not specified");
311 }
312 return null;
313 }
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000314 }
315 }
316 if (required) {
317 fatalError(name + " parameter not specified");
318 }
319 return null;
320 }
321
Constantin Kaplinsky972c2572002-05-30 14:19:02 +0000322 long readLongParameter(String name, long defaultValue) {
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000323 String str = readParameter(name, false);
Constantin Kaplinsky972c2572002-05-30 14:19:02 +0000324 long result = defaultValue;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000325 if (str != null) {
326 try {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000327 result = Long.parseLong(str);
328 } catch (NumberFormatException e) {
329 }
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000330 }
331 return result;
332 }
333
Constantin Kaplinsky7957ca12002-05-30 16:19:11 +0000334 double readDoubleParameter(String name, double defaultValue) {
335 String str = readParameter(name, false);
336 double result = defaultValue;
337 if (str != null) {
338 try {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000339 result = Double.valueOf(str).doubleValue();
340 } catch (NumberFormatException e) {
341 }
Constantin Kaplinsky7957ca12002-05-30 16:19:11 +0000342 }
343 return result;
344 }
345
wimba.com252eb3b2004-09-21 21:27:54 +0000346 int readIntParameter(String name, int defaultValue) {
347 String str = readParameter(name, false);
348 int result = defaultValue;
349 if (str != null) {
350 try {
351 result = Integer.parseInt(str);
352 } catch (NumberFormatException e) {
353 }
354 }
355 return result;
356 }
357
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000358 //
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000359 // fatalError() - print out a fatal error message.
360 //
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000361 public void fatalError(String str) {
362 System.out.println(str);
363
364 if (inAnApplet) {
365 vncContainer.removeAll();
366 if (rfb != null) {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000367 rfb = null;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000368 }
369 Label errLabel = new Label(str);
370 errLabel.setFont(new Font("Helvetica", Font.PLAIN, 12));
371 vncContainer.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 30));
372 vncContainer.add(errLabel);
373 if (inSeparateFrame) {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000374 vncFrame.pack();
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000375 } else {
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000376 validate();
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000377 }
378 Thread.currentThread().stop();
379 } else {
380 System.exit(1);
381 }
382 }
383
384
385 //
386 // This method is called before the applet is destroyed.
387 //
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000388 public void destroy() {
wimba.comd1f56df2004-11-01 16:18:54 +0000389 isQuitting = true;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000390 vncContainer.removeAll();
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000391 if (rfb != null) {
wimba.comd1f56df2004-11-01 16:18:54 +0000392 rfb.quit();
393 }
394 try {
395 rfbThread.join();
396 } catch (InterruptedException e) {
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000397 }
398 if (inSeparateFrame) {
wimba.com30ff9ed2004-11-01 20:54:08 +0000399 vncFrame.removeWindowListener(this);
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000400 vncFrame.dispose();
401 }
402 }
403
wimba.com252eb3b2004-09-21 21:27:54 +0000404 //
405 // Set the new width and height of the applet. Call when browser is resized to
406 // resize the viewer.
407 //
408 public void displaySize(int width, int height) {
409 dispW = width;
410 dispH = height;
411 if (!inSeparateFrame) {
412 vc.resizeEmbeddedApplet();
413 }
414 }
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000415
416 //
417 // Close application properly on window close event.
418 //
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000419 public void windowClosing(WindowEvent evt) {
Constantin Kaplinsky903009e2002-05-20 10:55:47 +0000420 vncContainer.removeAll();
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000421 if (rfb != null)
Constantin Kaplinsky903009e2002-05-20 10:55:47 +0000422 rfb = null;
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000423
424 vncFrame.dispose();
425 if (!inAnApplet) {
426 System.exit(0);
427 }
428 }
429
430 //
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000431 // Ignore window events we're not interested in.
432 //
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000433 public void windowActivated(WindowEvent evt) {
434 }
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000435
Constantin Kaplinsky72e47ef2008-04-18 17:48:16 +0000436 public void windowDeactivated(WindowEvent evt) {
437 }
438
439 public void windowOpened(WindowEvent evt) {
440 }
441
442 public void windowClosed(WindowEvent evt) {
443 }
444
445 public void windowIconified(WindowEvent evt) {
446 }
447
448 public void windowDeiconified(WindowEvent evt) {
449 }
450
Constantin Kaplinsky1215b992008-04-18 09:51:44 +0000451}