Source code: org/vrspace/vrmlclient/VRSpace.java
1 package org.vrspace.vrmlclient;
2
3 import java.applet.Applet;
4 import java.awt.*;
5 import java.awt.event.*;
6 import java.util.*;
7 import java.net.*;
8
9 import vrml.external.*;
10 import vrml.external.field.*;
11 import vrml.external.exception.*;
12
13 import org.vrspace.util.*;
14
15 /**
16 VRSpace applet<br>
17 Parameters:<br>
18 host - hostname, default origin host<br>
19 port - port to connect to<br>
20 username - username to login with<br>
21 password - password to login with<br>
22 logInfo - true/false<br>
23 logDebug - true/false<br>
24 logError - true/false<br>
25 logWarning - true/false<br>
26 intro - class imlementing Intro intefrace, started after init. Default: org.vrspace.vrmlclient.VRSpaceIntro<br>
27 @see Intro
28 */
29 public class VRSpace
30 extends Applet
31 implements Observer, EventOutObserver, ActionListener, WindowListener
32 {
33 public Browser browser;
34
35 private String host;
36 private int port = 8500;
37 public String login = null;
38 public String password = null;
39 //public String proxyURL = null;
40
41 String myClass;
42 long myId;
43
44 private boolean locked = false;
45 private boolean loginDisplayed = false;
46 private boolean readlogin = true;
47 private boolean nothingTyped = true;
48
49 public Node console;
50 EventInMFString conText;
51 EventInSFVec2f conPos;
52 EventInSFBool conHide;
53
54 public Node HUD;
55 public Node HUDLoader;
56 public EventInMFNode HUDLoad;
57
58 private long lastWrite;
59 public Node busy;
60
61 public EventInSFString serverMsg;
62 private EventOutSFString clientMsg;
63 private EventOutSFString userMsg;
64
65 public Node scene;
66 public Node bg; // background
67 public EventOutMFNode sceneChildren;
68 public EventOutMFNode hudChildren;
69 public Node dispatcherScript;
70 public Node loadTarget;
71 public EventInMFNode loadChildren;
72 public EventInMFNode unloadChildren;
73 public Node unloadTarget;
74 public Node movement;
75 EventOutSFVec3f translation_changed;
76 EventOutSFRotation rotation_changed;
77 EventInSFBool movementEnabled;
78 public Node fog;
79 EventInSFFloat visibility;
80 public Node navigationInfo;
81 EventOutSFBool navigationBound;
82 boolean navigationOn = true;
83 EventInMFString navigation;
84 public Node viewpoint;
85 public EventInSFVec3f translation;
86 public EventInSFRotation rotation;
87 //public Node chat;
88 //public EventOutSFBool chatActive;
89 //public boolean chatEnabled=false;
90
91 public Connection connection;
92 public ConnectionManager connMgr;
93 public URLLoader loader;
94 public Dispatcher dispatcher;
95 public SceneManager sceneMgr;
96 public MovementManager movementMgr;
97
98 String errorMsg = "";
99 Logger logger;
100 boolean useJava = true;
101 String introClass = "org.vrspace.vrmlclient.VRSpaceIntro";
102 Intro intro;
103
104 // UI stuff
105 private Keyboard keyboard;
106 private TextArea textArea;
107 private TextField textField;
108 private Frame logFrame;
109 private Button logButton;
110
111 // Applet init
112 public void init() {
113
114 logger = new Logger();
115
116 setBackground( Color.black );
117 setForeground( Color.green );
118 textArea = new TextArea( "", 25, 132, TextArea.SCROLLBARS_BOTH );
119 textField = new TextField( 80 );
120 // add( textArea );
121 logFrame = new Frame( "Session Log" );
122 logFrame.add( textArea );
123 logFrame.addWindowListener( this );
124
125 add( textField );
126
127 logButton = new Button( "?" );
128 logButton.setActionCommand( "logFrame" );
129 logButton.addActionListener(this);
130 add( logButton );
131
132 keyboard = new Keyboard();
133 // Setup key/text listeners
134 //textArea.addKeyListener( keyboard );
135 textField.addKeyListener( keyboard );
136 textField.addTextListener( keyboard );
137 keyboard.addObserver( this );
138
139 // get client parameters
140 host = getParameter( "host" );
141 if ( host == null ) {
142 host = getCodeBase().getHost();
143 }
144 String port = getParameter( "port" );
145 if ( port != null ) {
146 this.port = new Integer(port).intValue();
147 }
148 String login = getParameter( "username" );
149 if ( login != null ) {
150 this.login = login;
151 }
152 String password = getParameter( "password" );
153 if ( password != null ) {
154 this.password = password;
155 }
156
157 // not used:
158 //proxyURL = getParameter( "proxyURL" );
159 String tmp = getParameter( "logDebug" );
160 if ( tmp != null && "true".equals(tmp) ) {
161 Logger.logDebug( true );
162 } else {
163 Logger.logDebug( false );
164 }
165 tmp = getParameter( "logInfo" );
166 if ( tmp != null && "true".equals(tmp) ) {
167 Logger.logInfo( true );
168 } else {
169 Logger.logInfo( false );
170 }
171 tmp = getParameter( "logWarning" );
172 if ( tmp != null && "false".equals(tmp) ) {
173 Logger.logWarning( false );
174 } else {
175 Logger.logWarning( true );
176 }
177 tmp = getParameter( "logError" );
178 if ( tmp != null && "false".equals(tmp) ) {
179 Logger.logWarning( false );
180 } else {
181 Logger.logWarning( true );
182 }
183
184 // MS JVM Workaround: There is a race condition that can cause
185 // an applet to not appear (gray box). The issue is that the size of
186 // of the applet is never set. This workaround ensures it is set directly
187 // after the size of its parent it set. A manual workaround is to have
188 // the user resize the screen.
189 final Component componentToResize = this;
190 getParent().addComponentListener(
191 new ComponentListener() {
192 private boolean _beenResized = false;
193
194 public void componentResized( ComponentEvent e ) {
195 if (!_beenResized) {
196 componentToResize.setSize( e.getComponent().getSize() );
197 _beenResized = true;
198 }
199 }
200
201 public void componentMoved ( ComponentEvent e ) {}
202 public void componentShown ( ComponentEvent e ) {}
203 public void componentHidden( ComponentEvent e ) {}
204 }
205 );
206
207 }
208
209 // Look for VRML browser
210 synchronized boolean findBrowser() {
211 browser = null;
212 for ( int i = 0; i < 20 && browser == null; i++ ) {
213 try {
214 browser = Browser.getBrowser( this );
215 } catch ( Throwable e ) {
216 Logger.logError(e);
217 }
218 try {
219 Thread.sleep( 1000 );
220 } catch ( Exception e ) {
221 }
222 }
223 return (browser != null );
224 }
225
226 /**
227 Calls Browser.getNode(), but sets errormsg to node name
228 */
229 Node getNode( String name ) {
230 try {
231 return browser.getNode( name );
232 } catch ( Throwable t ) {
233 Logger.logError( "Couldn't find node "+name );
234 Logger.logError(t);
235 setForeground( Color.red );
236 textField.setText(t.toString()+" "+errorMsg);
237 return null;
238 }
239 }
240
241 // Applet start
242 public void start() {
243 try {
244 if ( findBrowser() ) {
245 try {
246 busy = browser.getNode( "VRSpace_Busy" );
247 } catch ( Throwable t ) {
248 Logger.logDebug( "No busy indicator: "+t );
249 }
250
251 // get nodes
252 dispatcherScript = getNode( "VRSpace_Dispatcher" );
253 scene = getNode("VRSpace_Scene");
254 //if ( browser.getName().indexOf( "Cortona" ) >= 0 ) {
255 loadTarget = getNode("VRSpace_Loader");
256 unloadTarget = getNode("VRSpace_Unloader");
257 //} else {
258 // loadTarget = getNode("VRSpace_Scene");
259 // unloadTarget = getNode("VRSpace_Scene");
260 //}
261 fog = getNode("VRSpace_Fog");
262 navigationInfo = getNode("VRSpace_NavigationInfo");
263 viewpoint = getNode("VRSpace_Viewpoint");
264 //chat = getNode("VRSpace_Chat");
265
266 // create EventOutObservers
267 connMgr = new ConnectionManager( this );
268 if ( browser.getName().indexOf( "Cortona" ) >= 0 ) {
269 loader = new CortonaLoader(this);
270 } else {
271 loader = new URLLoader(this);
272 }
273 sceneMgr = new SceneManager( this, 1000 );
274 movementMgr = new MovementManager(this);
275 dispatcher = new Dispatcher( this, sceneMgr );
276
277 // setup EventOutObservers
278 // network first
279 clientMsg = (EventOutSFString) dispatcherScript.getEventOut( "clientMsg" );
280 //clientMsg.advise( connMgr, "clientMsg" );
281 clientMsg.advise( this, "clientMsg" );
282 userMsg = (EventOutSFString) dispatcherScript.getEventOut( "userMsg" );
283 userMsg.advise( this, "userMsg" );
284
285 // user movement
286 try {
287 movement = getNode("VRSpace_Movement");
288 translation_changed = (EventOutSFVec3f) movement.getEventOut("position_changed");
289 rotation_changed = (EventOutSFRotation) movement.getEventOut("orientation_changed");
290 translation_changed.advise( this, "translation" );
291 rotation_changed.advise( this, "rotation" );
292 // we track movement only if VRSpace_NavigationInfo is bound
293 navigationBound = (EventOutSFBool) navigationInfo.getEventOut( "isBound" );
294 navigationBound.advise( this, "NavigationBound" );
295 // movement measurment on/off (proximity sensor on/off)
296 movementEnabled = (EventInSFBool) movement.getEventIn("enabled");
297 } catch ( Throwable t ) {
298 Logger.logInfo( "Movement tracking disabled: "+t.toString() );
299 }
300
301 // add the console
302 console = browser.getNode("VRSpace_Console");
303 conText = (EventInMFString) console.getEventIn( "set_string" );
304 conPos = (EventInSFVec2f) console.getEventIn( "set_cursor" );
305 try {
306 conHide = (EventInSFBool) console.getEventIn( "set_hide" );
307 } catch ( Throwable t ) {
308 Logger.logInfo( "Console cannot be hidden" );
309 }
310 // movement tracking should be checked before
311 if ( browser.getName().indexOf( "blaxxun" ) >= 0 || browser.getName().indexOf( "Contact" ) >= 0 ) {
312 useJava = false;
313 }
314 HUD = getNode("VRSpace_HUD");
315 HUDLoader = getNode("VRSpace_HUDLoader");
316 hudChildren = (EventOutMFNode) HUD.getEventOut("children_changed");
317 hudChildren.advise( this, "HUD" );
318 /*
319 if ( useJava ) {
320 // add console
321 String[] tmp = {"console.wrl"};
322 browser.createVrmlFromURL( tmp, HUDLoader, "children" );
323 } else {
324 // add javascript console
325 String[] tmp = {"console-js.wrl"};
326 browser.createVrmlFromURL( tmp, HUDLoader, "children" );
327 }
328 */
329
330 // look for nodes
331 try {
332 bg = getNode( "VRSpace_Background" );
333 } catch ( Throwable t ) {
334 Logger.logDebug( "No VRSpace_Background node: "+t );
335 }
336
337 // changes to the scene
338 sceneChildren = (EventOutMFNode) scene.getEventOut( "children_changed" );
339 //sceneChildren.advise( loader, "loadedTransform" );
340 sceneChildren.advise( this, "loadedTransform" );
341
342 // chat on/off
343 //chatActive = (EventOutSFBool) chat.getEventOut("active");
344 //chatActive.advise( this, "chatActive" );
345
346 // movement synchronization time (seconds)
347 movementMgr.setSync((long) (((EventOutSFFloat) dispatcherScript.getEventOut( "movement_sync" )).getValue() * 1000));
348 // EventIn to receive network events
349 serverMsg = (EventInSFString) dispatcherScript.getEventIn( "serverMsg" );
350 // EventIn for visibility range control
351 visibility = (EventInSFFloat) fog.getEventIn( "set_visibilityRange" );
352 // Navigation type control
353 navigation = (EventInMFString) navigationInfo.getEventIn( "set_type" );
354 // Viewpoint coordinates
355 translation = (EventInSFVec3f) viewpoint.getEventIn( "set_position" );
356 rotation = (EventInSFRotation) viewpoint.getEventIn( "set_orientation" );
357 // changes to the scene
358 //if ( browser.getName().indexOf("Cortona") > 0 ) {
359 loadChildren=(EventInMFNode) loadTarget.getEventIn( "children" );
360 unloadChildren=(EventInMFNode) unloadTarget.getEventIn( "children" );
361 //} else {
362 // loadChildren=(EventInMFNode) loadTarget.getEventIn( "addChildren" );
363 // unloadChildren=(EventInMFNode) loadTarget.getEventIn( "removeChildren" );
364 //}
365
366 if ( HUDLoader != null ) {
367 HUDLoad = (EventInMFNode) loadTarget.getEventIn( "children" );
368 }
369 // Login...
370 // Other threads are closed before, and started after login
371 initiateLogin();
372 Logger.logDebug( "VRSpace started" );
373 /**
374 try {
375 Class c = Class.forName( "com.trapezium.chisel.Chisel" );
376 Class[] args = new Class[]{ (new String[]{}).getClass() };
377 Object[] arg = { new String[]{"-loadfromjar","-forcejfc","+http://localhost/portal/" }};
378 c.getMethod( "main", args ).invoke( null, arg );
379 Logger.logDebug( "Chisel started" );
380 } catch ( Throwable t ) {
381 Logger.logError(t);
382 }
383 */
384 } else {
385 Logger.logError("No VRML browser!");
386 }
387 } catch ( Throwable e ) {
388 setForeground( Color.red );
389 textField.setText(e.toString()+" "+errorMsg);
390 Logger.logError(e);
391 Logger.logError("Unable to start VRSpace client!");
392 }
393 }
394
395 public void stop() {
396 try {
397 movementMgr.active=false;
398 loader.active=false;
399 if ( connection != null && connection.isActive() ) {
400 connection.close();
401 }
402 } catch (Throwable e) {
403 Logger.logError(e);
404 }
405 Logger.logDebug( "VRSpace stopped" );
406 }
407
408 public void destroy() {
409 // logout? seems it crashes netscape
410 // connection.send( "quit" );
411 movementMgr.active=false;
412 logFrame.hide();
413 Logger.logDebug( "VRSpace unloaded" );
414 }
415
416 // Login start
417 public void initiateLogin() {
418 try {
419 // this stops movementMgr Thread:
420 movementMgr.active=false;
421
422 Logger.logDebug( "login" );
423 //((EventInSFBool) console.getEventIn("autoHide")).setValue(false);
424 clear();
425 // writeat(0,0, "VRSpace");
426 if ( ( login == null ) || ( password == null ) ) {
427 displayLogin();
428 }
429 textField.setText("");
430 textField.requestFocus();
431 //((EventInSFString) console.getEventIn("set_xyzgo")).setValue("-.05 .03 -.20 1");
432 //(new Thread(new ConsoleThread())).start();
433
434 // Intro frozen for release.
435 /*try {
436 Class intro = Class.forName(introClass);
437 this.intro = (Intro)intro.newInstance();
438 this.intro.start( this );
439 } catch (Throwable thr) {
440 Logger.logError(thr);
441 }
442 */
443
444 textArea.setText("");
445 // textArea.requestFocus();
446 } catch (Throwable t) {
447 t.printStackTrace();
448 }
449 }
450 public class ConsoleThread implements Runnable {
451 public void run() {
452 /*
453 while (!useJava && nothingTyped) {
454 displayLogin();
455 ((EventInSFString) console.getEventIn("set_xyzgo")).setValue("-.05 .03 -.20 1");
456 try {
457 Thread.sleep(1000);
458 } catch (InterruptedException e) {
459 }
460 }
461 */
462 while (true) {
463 try {
464 if ( connection != null && connection.isActive() && !movementMgr.moving && (lastWrite + 60000 > System.currentTimeMillis()) ) {
465 ((EventInSFString) console.getEventIn("set_xyzgo")).setValue("-.15 .03 -.20 1");
466 }
467 Thread.sleep(5000);
468 } catch (InterruptedException e) {
469 }
470 }
471 }
472 }
473 private void displayLogin() {
474 writeat(0,0, "VRSpace server "+host+":"+port);
475 writeat(2,0, "login :");
476 writeat(3,0, "password:");
477 pos( 2, 10 );
478
479 loginDisplayed = true;
480 }
481
482 /**
483 Login & password input, connect to server,
484 start Connection and MovmementManager
485 */
486 private void readLogin( String arg ) {
487 if (login == null || password == null) {
488 if ( ! loginDisplayed ) {
489 displayLogin();
490 }
491 if ( arg == null ) {
492 // TextEvent
493 //write( textArea.getText().trim() );
494 String text = textField.getText().trim();
495 if ( readlogin ) {
496 //write( text );
497 writeat( 2, 10, text );
498 } else if (text.length() > 0 ){
499 StringBuffer s = new StringBuffer( text.length() );
500 for ( int i = 0; i<text.length(); i++) {
501 s.append('*');
502 }
503 //write( s.toString() );
504 writeat( 3, 10, s.toString() );
505 }
506 if ( text.length() > 0 ) {
507 nothingTyped = false;
508 }
509 } else if ( arg.equals( "Enter" ) ) {
510 // string typed
511 if ( readlogin ) {
512 // login = textArea.getText().trim();
513 login = textField.getText().trim();
514 pos( 3, 10 );
515 readlogin = false;
516 } else {
517 // password = textArea.getText().trim();
518 password = textField.getText().trim();
519 readlogin = true;
520 login();
521 }
522 //textArea.setText("");
523 textField.setText("");
524 }
525 } else {
526 login();
527 }
528 }
529
530 private void login() {
531 try {
532 // connect
533 connection = new Connection( host, port, login, password );
534 // connected
535 connection.addObserver( connMgr );
536 if ( intro != null ) {
537 try {
538 intro.stop();
539 } catch ( Throwable t ) {
540 //who cares
541 //Logger.logDebug( t.toString() );
542 Logger.logError( t );
543 }
544 }
545 // start movement manager
546 movementMgr.active=true;
547 movementMgr.setMovement(false);
548 (new Thread(movementMgr)).start();
549 // start loader
550 loader.active = true;
551 loader.start();
552 // move console around (hide)
553 //((EventInSFBool) console.getEventIn("autoHide")).setValue(true);
554 //((EventInSFString) console.getEventIn("set_xyzgo")).setValue("-.15 .03 -.20 1");
555 clear();
556 /*
557 try {
558 consoleOpen = (EventOutSFTime) console.getEventOut("open");
559 consoleOpen.advise( this, "consoleOpen" );
560 } catch ( Exception e ) {
561 Logger.logError( "Cannot listen console.open - "+e );
562 }
563 */
564 } catch (ConnectionException e) {
565 String msg = e.getMessage();
566 if ( msg == null ) {
567 msg = e.toString();
568 }
569 writeat( 1,0,msg );
570 //if ( msg.length()>5 && "-login".equals( msg.substring(0,6) ) ) {
571 login = null;
572 password = null;
573 //}
574 pos( 2, 10 );
575 }
576 }
577 // Keyboard input handling
578 public void update( Observable o, Object argument ) {
579 String arg = (String) argument;
580 if ( o instanceof Keyboard ) {
581 if ( connection == null || !connection.isActive()) {
582 readLogin( arg );
583 } else {
584 //if ( arg == null && textField.getText().trim().length() > 0 ) {
585 if ( "Enter".equals(arg) ) {
586 // TextEvent
587 /*
588 if ( chatEnabled ) {
589 connection.send( myClass+" "+myId+" say "+textField.getText().trim() );
590 } else {
591 connection.send( textField.getText().trim() );
592 }
593 */
594 try {
595 if ( textField.getText().charAt(0) == '/' ) {
596 // commands begin with /
597 connection.send( textField.getText().substring(1).trim() );
598 } else {
599 // default command is say
600 connection.send( myClass+" "+myId+" say "+textField.getText().trim() );
601 }
602 writeln( "> "+textField.getText().trim() );
603 } catch (Throwable t) {
604 Logger.logError(t);
605 }
606 textField.setText("");
607 }
608 }
609 } else if ( o instanceof Connection ) {
610 // moved to new Observer - ConnectionManager
611 Logger.logError( "BEEP!" );
612 }
613 }
614
615 int curRow = 9;
616 int curCol = 0;
617 String[] text = new String[10];
618 int maxLength = 60;
619 // Misc text output functions
620 public void clear() {
621 for (int i = 0; i < text.length; i++) {
622 text[i] = "";
623 }
624 pos( 0, 0 );
625 conText.setValue( text );
626 if ( conHide != null ) {
627 conHide.setValue( true );
628 }
629 }
630 public void writeat( int row, int col, String s ) {
631 //System.out.println( "writeat "+row+" "+col+" "+s );
632 try {
633 if ( col >= text[row].length() ) {
634 StringBuffer tmp = new StringBuffer( text[row] );
635 for ( int i = text[row].length(); i < col; i++ ) {
636 tmp.append(' ');
637 }
638 tmp.append( s );
639 text[row] = tmp.toString();
640 } else {
641 text[row] = text[row].substring( 0, col ) + s;
642 }
643 conText.setValue( text );
644 pos( row, text[row].length() );
645 } catch ( Exception e ) {
646 e.printStackTrace();
647 //System.out.println( row );
648 //System.out.println( col );
649 //System.out.println( conText );
650 }
651 }
652
653 public void write( String s ) {
654 writeat( curRow, curCol, s );
655 //cursor( curRow, text[curRow].length()+1 );
656 }
657
658 public void pos( int row, int col ) {
659 //System.out.println( "pos "+row+" "+col );
660 cursor( row, col+1 );
661 curCol = col;
662 curRow = row;
663 }
664 public void writeln( String s ) {
665 //System.out.println( "writeln "+s );
666 try {
667 addLine(s);
668 conText.setValue(text);
669 pos( curRow, 0 );
670 //curCol=0;
671 cursor(curRow,-2);
672
673 textArea.append( s );
674 textArea.append( "\n" );
675
676 } catch ( Exception e ) {
677 e.printStackTrace();
678 }
679 }
680 void addLine( String s ) {
681 if ( curRow < text.length-1 ) {
682 text[++curRow] = s;
683 } else {
684 for ( int i = 0; i < text.length-1; i++ ) {
685 text[i] = text[ i+1 ];
686 }
687 text[text.length-1]=s;
688 }
689 }
690 public void cursor(int row, int col) {
691 float[] tmp = { row, col };
692 conPos.setValue( tmp );
693 }
694
695 public void say( NodeManager who, String what ) {
696 String name = who.getName();
697 if ( name == null ) {
698 name = who.className+' '+who.id;
699 }
700 textArea.append( name );
701 textArea.append( ": " );
702 textArea.append( what );
703 textArea.append( "\n" );
704
705 StringTokenizer st = new StringTokenizer( what, " " );
706 StringBuffer output = new StringBuffer( name );
707 output.append(": ");
708 while (st.hasMoreTokens()) {
709 String token = st.nextToken();
710 if ( output.length() + token.length() > maxLength ) {
711 //writeln( output.toString() );
712 addLine( output.toString() );
713 output = new StringBuffer();
714 for ( int i = 0; i < name.length(); i++ ) {
715 output.append( ' ' );
716 }
717 output.append( ": " );
718 }
719 output.append( token );
720 output.append( ' ' );
721 }
722 if ( output.length() > 0 ) {
723 addLine( output.toString() );
724 //writeln( output.toString() );
725 }
726 conText.setValue(text);
727 pos( curRow, 0 );
728 cursor(curRow,-2);
729 }
730 /*
731 public TextArea getOutput() {
732 return textArea;
733 }
734 */
735 public TextField getOutput() {
736 return textField;
737 }
738
739 public Keyboard getInput() {
740 return keyboard;
741 }
742
743 public void callback ( EventOut ev,
744 double timestamp,
745 Object userdata
746 )
747 {
748 try {
749 if ( userdata.equals("translation")||userdata.equals("rotation") ) {
750 if (!locked && navigationOn) {
751 locked=true;
752 movementMgr.callback( ev, timestamp, userdata );
753 locked=false;
754 }
755 } else if ( userdata.equals("loadedTransform") ) {
756 loader.callback( ev, timestamp, userdata );
757 //unlock();
758 } else if ( userdata.equals("clientMsg") ) {
759 connMgr.callback( ev, timestamp, userdata );
760 } else if ( userdata.equals("userMsg") ) {
761 connMgr.callback( ev, timestamp, userdata );
762 } else if ( userdata instanceof Long ) {
763 Transform t=sceneMgr.getTransform( ((Long)userdata).longValue() );
764 if ( t != null ) {
765 t.callback( ev, timestamp, userdata );
766 }
767 //unlock();
768 /*
769 } else if ( userdata.equals("chatActive") ) {
770 chatEnabled = ((EventOutSFBool)ev).getValue();
771 if ( chatEnabled ) {
772 textField.requestFocus();
773 }
774 */
775 } else if ( userdata.equals("NavigationBound") ) {
776 navigationOn = ((EventOutSFBool)ev).getValue();
777 Logger.logDebug( "NavigationInfo bound: "+navigationOn);
778 /*
779 } else if ( userdata.equals( "HUD" ) ) {
780 // hud children changed - console added
781 Logger.logDebug( "Console added" );
782 Node[] hudChildren = ((EventOutMFNode)ev).getValue();
783 console = hudChildren[ hudChildren.length - 1 ];
784 if ( movement != null ) {
785 browser.addRoute( movement, "position_changed", console, "movement" );
786 }
787 ((EventInSFBool)console.getEventIn("VRObject_Online")).setValue(true);
788 */
789 /*
790 } else if ( userdata.equals("consoleOpen") ) {
791 String[] conText = ((EventOutMFString) console.getEventOut( "text_changed" )).getValue();
792 if ( consoleFrame == null ) {
793 consoleFrame = new Frame( "Console" );
794 consoleFrame.setLayout( new GridLayout( conText.length+1,1 ));
795 //consoleFrame.setSize( 300, 200 );
796 //consoleFrame.show();
797 consoleFrame.pack();
798 } else {
799 consoleFrame.removeAll();
800 }
801 for( int i = 0; i < conText.length; i++ ) {
802 consoleFrame.add( new Label( conText[i] ));
803 }
804 Button close = new Button( "Close" );
805 close.addActionListener( this );
806 consoleFrame.add( close );
807 //consoleFrame.validate();
808 consoleFrame.pack();
809 consoleFrame.show();
810 consoleFrame.requestFocus();
811 */
812 }
813 } catch (Throwable t) {
814 Logger.logError(t);
815 }
816 }
817 private synchronized void lock() {
818 locked=true;
819 movementEnabled.setValue(false);
820 }
821 public void unlock() {
822 if ( locked ) {
823 movementEnabled.setValue(true);
824 locked=false;
825 }
826 }
827 public synchronized boolean lock( long wait ) {
828 while (locked) {
829 try {
830 Thread.sleep( wait );
831 } catch ( InterruptedException e ) {
832 }
833 }
834 movementEnabled.setValue(false);
835 locked = true;
836 return locked;
837 }
838 public void actionPerformed( ActionEvent e ) {
839 if ( e.getActionCommand().equals("logFrame") ) {
840 // set focus to chat window
841 if ( ! logFrame.isVisible() ) {
842 logFrame.pack();
843 }
844 logFrame.show();
845 //logFrame.requestFocus();
846 textArea.requestFocus();
847 } else {
848 Logger.logError( "Invalid action event: "+e );
849 }
850
851 //consoleFrame.hide();
852 }
853 public String getInfo() {
854 return browser.getName() + " V"+browser.getVersion() + " OS: " +
855 System.getProperty("os.name") + " "+
856 System.getProperty("os.version") + " "+
857 System.getProperty("os.arch") ; //+" "+
858 //System.getProperty("user.name");
859 }
860 public void setBusy( boolean busy ) {
861 if ( this.busy != null ) {
862 if ( busy ) {
863 ((EventInSFTime)this.busy.getEventIn( "stop" )).setValue(System.currentTimeMillis()/1000);
864 } else {
865 ((EventInSFTime)this.busy.getEventIn( "start" )).setValue(System.currentTimeMillis()/1000);
866 }
867 }
868 }
869 public String rewriteURL( String url ) {
870 URL tmp = null;
871 String ret = url;
872 try {
873 tmp = new URL( ret );
874 } catch ( MalformedURLException e ) {
875 try {
876 if ( url.indexOf("/") == 0 ) {
877 //ret = getCodeBase().getProtocol()+"://"+getCodeBase().getHost()+url;
878 ret = getCodeBase().getProtocol()+"://"+getCodeBase().getHost()+":"+getCodeBase().getPort()+url;
879 tmp = new URL( ret );
880 } else {
881 String s = getDocumentBase().toString();
882 ret = s.substring( 0,s.lastIndexOf("/"))+"/"+url;
883 tmp = new URL( ret );
884 }
885 } catch ( MalformedURLException e1 ) {
886 Logger.logError(e1);
887 }
888 }
889 return ret;
890 }
891
892 // WindowListener iface for chat window
893 public void windowActivated( WindowEvent e ) {
894 }
895 public void windowClosed( WindowEvent e ) {
896 }
897 public void windowClosing( WindowEvent e ) {
898 logFrame.hide();
899 }
900 public void windowDeactivated( WindowEvent e ) {
901 }
902 public void windowDeiconified( WindowEvent e ) {
903 }
904 public void windowIconified( WindowEvent e ) {
905 }
906 public void windowOpened( WindowEvent e ) {
907 }
908 }