This annex provides a detailed description of the Java language binding to the services defined in this standard. Note that support for the Java platform is not required by this standard but any access of the Java platform as an external application to a VRML browser shall conform with the requirements specified in this annex.
The Javatm platform is an object-oriented, hardware and operating system independent, multi-threaded, general-purpose application environment developed by Sun Microsystems, Inc. The Java platform consists of the language, the virtual machine, and a set of core class libraries. A conforming Java platform implements all three components according to their specifications. See 2.[JAVA] for a description of the language, the virtual machine, and the three core classes java.lang, java.util, and java.io. The other core class libraries, which are not used in this annex, are described in ISO/IEC 14772-1 E.[JAPI].
For historical reasons, the Java language binding to the EAI does not implement the full set of capabilities defined in the main specification. It implements the minimum requirements (see 7.3 Minimum Support Requirements). Restrictions imposed by this implementation on the services specification are noted individually in B.5 Services Binding.
See Table B.1 for the contents of this annex.
The following type-setting conventions are used to indicate a particular meaning to the text in this document.
name |
Words written in monospaced font are direct description of a particular Java class, field or property. This text may also provide a link to the specific documentation (provided in javadoc style documentation) to provide greater definition of the information |
methodName() |
Indicates a particular java method call. This may be representative of the general method name (where there are overloaded versions of the method) or just the method. No arguments definitions are provided unless needed in context to define the particular method specifically. The capitalization of the method name exactly follows the name of the method |
ClassName.methodName() |
The first word indicates the name of the class and is qualified with the method name. The capitalization of the class name follows the exact naming of the class. The method argument presentation is the same as that for the plain method name. |
package.name.ClassName |
All words up to the class name represent the package definition that the class belongs to. Referred to as the fully qualified class name. The last word is the name of the class. Capitalization follows the exact definition of the class and package. |
As with scripts within the VRML scene, the EAI allows access to the full functionality of the Browser script interface. Browser state can be queried, routes can be added and deleted, and new nodes can be created. The EAI extends the basic browser interface with a number of extra capabilities such as retrieving node references and registering interest in browser events. This annex provides an implementation in the Java language.
Annex B Java platform scripting reference of 2.VRML defines a Java specification to the script interface. Due to the differing capabilities of the EAI and scripting interface, the browser interfaces are not interchangeable between the two environments. This applies to all of the classes defined in ISO/IEC 14772-1 B Java platform scripting reference.
The Java platform provides an implementation of the EAI specification. It provides a complete binding to the specification within the restrictions and implementation specific capabilities as defined in this standard. The specification provides a browser implementation independent way of accessing the browser capabilities through the Java language.
Java support is not required for a conforming implementation of the EAI. If a browser supports a Java language interface from an external environment, it shall conform with all of the requirements specified in this annex.
An implementation shall not modify the classes defined in this specification with their own specific methods or additional methods. The Java reflection APIs shall be used to test this aspect of conformance.
A VRML browser that can be accessed through a Java API can take one of two forms. The first form is as a plugin to a web browser. The Java code exists as an applet and accesses the plugin. The second form is a component that is available to be directly embedded in the Java framework. This form will subclass the Java Component class found in java.awt.Component.
Implementation dependent for the scope of this annex is defined to be the browser writer implementation of the Java classes and how they interact with the environment and the VRML browser.
This specification does not implement the full capabilities of the EAI specification. Additional capabilities may be provided by individual implementations but shall not form part of the standard vrml.eai package hierarchy and classes as defined in this specification. Any implementation dependent provision of these capabilities shall be provided under a non-VRML package such as the vendor's own hierarchy. The listing of the implementation of all Java classes used for binding to the services is provided in B.6 Java Class Hierarchy.
The action type is dependent on the method used. Table B.2 defines the mapping between each service, the valid action types for that service and the Java implementation of that action. Actions are mapped as method names describing the action rather than strict primitive types.
Table B.2 — EAIAction to Java implementation mapping
Service |
Action Type |
Java Implementation |
Dynamic Route Handling |
Add Route |
Browser.addRoute() |
Delete Route |
Browser.deleteRoute() |
|
Update Control |
Begin Update |
Browser.beginUpdate() |
|
End Update |
Browser.endUpdate() |
Register Browser Interest |
Add |
Browser.addBrowserListener() |
|
Remove |
Browser.removeBrowserListener() |
Register Event Interest |
Add |
EventOut.addVrmlEventListener() |
|
Remove |
EventOut.removeVrmlEventListener() |
The data type is implemented as the class vrml.eai.VrmlComponent. The capability to obtain a EAIBrowserRef is implemented in the getBrowser() method which returns an instance of the vrml.eai.Browser class.
The data type is implemented as a java.lang.String.
The browser reference type is defined to be an instance of the vrml.eai.Browser class. The Browser class is defined as an implementation independent Java interface which is then subclassed to provide vendor specific
The data type is implemented as a java.lang.String. The NULL value is defined as the Java null primitive type.
Field access is defined by the hierarchy of inheritance of classes used to represent the EAIFieldID. The base class vrml.eai.field.BaseField defines the basic field properties which are then subclassed. These subclasses vrml.eai.field.EventIn and vrml.eai.field.EventOut provide representations of the access types.
There is a distinct difference between the access type of the underlying field that was retrieved from the node and how it is represented by the subclasses. A request is made of the node to access any field to be viewed as either an eventIn (see Node.getEventIn()) or and eventOut (see Node.getEventOut()). The node implementation then either returns the type or generates an error condition. The acceptable conditions for successful completion of the request are defined in Table B.3
Table B.3 — Rules for mapping VRML Field types to Java field classes
|
|
Java Classes |
|
|
|
EventIn |
EventOut |
VRML Field Types |
field |
Error |
Error |
eventIn |
yes |
Error |
|
eventOut |
Error |
yes |
|
exposedField |
yes |
yes |
The field identifier is represented as an instance of the class vrml.eai.field.BaseField. Note that since the Java class hierarchy design allows two representations of a field using the EventIn and EventOut classes, it is possible to have two disparate references to the same field. The only time that this occurs is when referencing an exposedField of a node. The class implementation shall override the equals() method such that checking for equality in the above case shall return a result of true.
The following example illustrates the correct behaviour associated with this. The node reference has been obtained to a transform node.
Node transform; // value has been assign
previously
EventIn
set_translation = transform.getEventIn("set_translation");
EventOut
translation_changed = transform.getEventOut("translation_changed");
Boolean
same_event_in;
same_event_in = set_translation.equals(translation_changed);
System.out.println("Checking
set translation equals " +
"translation changed: " +
same_event_in);
// now check the reverse case
same_event_in =
translation_changed.equals(set_translation);
System.out.println("Checking
translation changed equals " +
"set translation: " +
same_event_in);
The resulting execution of this code segment should produce on standard output
Checking set
translation equals translation changed: true
Checking
translation changed equals set translation: true
The name of the field is implemented as a java.lang.String.
The field type may be represented in two alternative fashions.
The first alternative is provided through getType() method provided in the BaseField class. This returns an int which has one of the values defined by the constant types also defined in that class as shown in Table B.4.
Table B.4 —
Mapping of VRML Field type to Java representation
VRML Field type Java
representation MFColor static
final int MFColor MFFloat static
final int MFFloat MFInt32 static
final int MFInt32 MFNode static
final int MFNode MFRotation static
final int MFRotation MFString static
final int MFString MFTime static
final int MFTime MFVec2f static
final int MFVec2f MFVec3f static
final int MFVec3f SFBool static
final int SFBool SFColor static
final int SFColor SFFloat static
final int SFFloat SFImage static
final int SFImage SFInt32 static
final int SFInt32 SFNode static
final int SFNode SFRotation static
final int SFRotation SFString static
final int SFString SFTime static
final int SFTime SFVec2f static
final int SFVec2f SFVec3f static
final int SFVec3f The second alternative is provided by the class
hierarchy. The EventIn and EventOut classes are further derived to provide implementations of
the exact field type. These classes are defined in the vrml.eai.field package. A list of all the classes for each field type and
access type is provided in B.5.4 Field Services.
The field value is defined on a per class and per field type instance. See
the definitions of the classes in the vrml.eai.field package for the exact
definition of each type. The data type is implemented as the Java primitive type float. A null
value is defined as the value 0.0f. The data type is implemented as the Java primitive type float. A null
value is defined as the value 0.0f. The node identifier is represented as an instance of vrml.eai.Node. The node type is represented as a java.lang.String. The data type is represented by the values in the Table B.5. The table
defines the services that use the data type, the method of the BrowserFactory
class and the lists of argument types that method takes. Table B.5 —
Mapping of EAIParameterList to Java parameter lists Service method Java Parameters getBrowser getBrowser() java.applet.Applet getBrowser() java.applet.Applet,
String, int getBrowser() java.net.InetAddress,
int createBrowser createVrmlComponent() None The data type is implemented as an array of java.lang.String. Key/Value pairs are declared
in a single string in the following format with the '=' character as the
separator. Whitespace surrounding the key and value are ignored although
whitespace inside the key and value are legal. The following are considered valid values (as well as permutations of the
given examples): "key=value" The requestor ID is represented as an instance of one of two classes
depending on what information is being requested. The requestor ID is an instance of the class implementing the interface vrml.eai.event.BrowserListener
when the service request is browser_event_interest.
The requestor ID is an instance of the class implementing the interface vrml.eai.event.VrmlEventListener
when the service request is field_event_interest.
The URL is implemented as a java.lang.String. The string is implemented as a java.lang.String. Java implementations of the errors rely on a set of derived classes based on
the EAIError type. The error type is implemented as the class vrml.eai.VrmlException. This exception
is in turn derived from the standard Java error type of java.lang.RuntimeException.
All exceptions(errors) defined in this specification shall be derived from VrmlException. The error type is implemented as the class vrml.eai.NoSuchBrowserException. The error type is implemented as the class vrml.eai.ConnectionException. The error type is implemented as two separate dual purpose exception classes
depending on their scope. vrml.eai.InvalidBrowserException
is used to indicate an EAIBrowserRef has been
disposed of. The error type is implemented as two separate exceptions based on the
implementation of EAINodeID and the rules defined in Table B.2. These classes also
derive from vrml.eai.field.InvalidFieldException.
vrml.eai.field.InvalidEventInException
is used to indicate the named field is not accessible as an eventIn from the Node.getEventIn()
method. vrml.eai.field.InvalidEventOutException
is used to indicate the named field is not accessible as an eventOut from the Node.getEventOut()
method. The error type is implemented as the class vrml.eai.InvalidBrowserException. The error type is expressed as different exceptions dependent on the
situation. The Browser.getNode()
method uses the InvalidNodeException.
The Node
class getEventIn()
and getEventOut()
methods use the InvalidEventInException
and InvalidEventOutException
types respectively. The error type is implemented as the class vrml.eai.InvalidNodeException. The error type is implemented as the class vrml.eai.field.InvalidFieldException.
Note that there are two derived classes from this class (InvalidEventInException
and InvalidEventOutException)
that may be used at times where this error may be generated. The error type is implemented as the class vrml.eai.InvalidURLException. The error type is implemented as the class vrml.eai.InvalidVrmlException. The error type is implemented as the class vrml.eai.URLUnavailableException. The Java implementation of the event handling and types is based around the
Java 1.1 AWT event listener model. A single event class is used to encapsulate
the type of event and then parameters defining the actual event item that
occurred. vrml.eai.event.BrowserEvent
The event type is implemented in the class vrml.eai.event.BrowserEvent. Each of the
individual events are expressed as actions that the event then passes to the
registered listeners. The action type of the individual event is available
through the getID() method. The event type is implemented as the INITIALIZED value for the browser event
ID. The event type is implemented as the SHUTDOWN value for the browser event ID.
The event type is implemented as the CONNECTION_ERROR value for the browser
event ID. The event type is implemented as the URL_ERROR value for the browser event
ID. The event type is implemented as the class vrml.eai.event.VrmlEvent. This class
contains methods for obtaining the source of the event, the time (in VRML time)
and any user defined data that occurred with the event. This specification provides a set of implementation independent base classes
that represent the possible interactions with the VRML scene through the
External Authoring Interface. Browser specific implementation dependencies
shall to remain hidden to the general user. Where classes are declared to be
abstract, it is expected that the browser specific implementation shall derive
from these classes as required. An implementation shall not modify these base classes with their own
specific methods or additional methods. The difference between the two forms of the browser is limited to how to
initially obtain the browser reference. Once this has been obtained, the
services provided shall not differ. The term application is used to describe
the Java code that wishes to access the VRML browser, regardless of how the
initial reference to the browser was obtained. A browser that supports the EAI Java implementation may supply the base
classes as part of the distribution. The design of the classes is such that only
one copy of the classes defined by this application needs to be placed on the
machine although multiple copies are permitted. Implementation dependent
classes need only to be supplied with the browser and accessed by setting the
CLASSPATH to point to the appropriate implementation dependent classes. It is recommended that the implementation of the classes defined by this
specification are placed in either a zip file or Java Archive (JAR file) under
the <JAVAHOME>/lib
directory. Where a VRML browser is supplied as a standalone application, the minimum
required version of Java Virtual Machine support is version 1.1. VRML Browsers that operate as a plugin to general
purpose web browsers may support whatever version of Java that the web browser
supports. In the case where the web browser does not support any Java, or
multiple versions, the minimum of version 1.1 shall be required. The Java bindings to the EAI shall be provided under the vrml.eai top
level package structure and are organized in the following manner.
B.3.1.10 EAIFieldValue
B.3.1.11 EAIFrameRate
B.3.1.12 EAINavSpeed
B.3.1.13 EAINodeID
B.3.1.14 EAINodeType
B.3.1.15 EAIParameterList
B.3.1.16 EAIPropertyList
"key = value
"
" key =
value"
"a key= some
value"
"a
key =some value"B.3.1.17 EAIRequesterID
B.3.1.18 EAIURL
B.3.1.19 EAIString
B.3.2 Error data types
B.3.2.1 EAIError
B.3.2.2 EAI_BROWSER_UNAVAILABLE
B.3.2.3 EAI_CONNECTION_ERROR
B.3.2.4 EAI_DISPOSED
vrml.eai.InvalidNodeException
is used to indicate an EAINodeID has been disposed of.B.3.2.5 EAI_INVALID_ACCESS_TYPE
B.3.2.6 EAI_INVALID_BROWSER
B.3.2.7 EAI_INVALID_NAME
B.3.2.8 EAI_INVALID_NODE
B.3.2.9 EAI_INVALID_FIELD
B.3.2.10
EAI_INVALID_URL
B.3.2.11
EAI_INVALID_VRML
B.3.2.12
EAI_URL_UNAVAILABLE
B.3.3
Event Types
B.3.3.1
Concepts
B.3.3.2 EAIBrowserEvent
B.3.3.3 EAI_B_Initialized
B.3.3.4 EAI_B_Shutdown
B.3.3.5 EAI_B_ConnectionError
B.3.3.6 EAI_B_URLError
B.3.3.7 EAIFieldEvent
B.4 Language specific concepts
B.4.1 Class implementation
B.4.1.1 Introduction
B.4.1.2 Provision of Classes
B.4.1.3 Required Java version
B.4.1.4 Package Structure
vrml.eai |
The basic working classes for the interface to the browser and nodes. |
vrml.eai.event |
Event classes and listener interfaces |
vrml.eai.field |
Classes for accessing fields |
A session for Java based communications is dependent on the type of handle established: applet or component.
The difference between the two forms of the browser is limited to how to initially obtain the browser reference. Once this has been obtained, the services provided shall not differ. The term application is used to describe the Java code that wishes to access the VRML browser, regardless of how the initial reference to the browser was obtained.
A VRML browser established by creating a new instance of the vrml component class. This instance may then be inserted into the Java GUI framework following any Java restrictions that may be imposed on the class as a result of adding it to an AWT Container.
At the point where the browser object is instantiated, it contains no scene graph. To load the initial scene the loadURL() method is called. If the application has registered as a listener for browser events, it shall receive the initialize event as specified in the EAI specification.
Components follow the normal rules for any class derived from java.awt.Component. It may be freely added to any container and have extra components added that may partially or completely obscure the area of the window that is being used to render the VRML world. At no time shall the actions of other components that partially or complete obscure the VRML browser cause execution of the VRML event model to suspend or complete.
Note that this allows application code to draw over the top of the VRML window and attach any Java.awt.event listener as it requires without modifying the functionality of the VRML browser and vice versa.
When the VRML browser exists as an element embedded in a HTML page to which a Java applet has access, it must use the underlying web browser APIs to access the plugin. The session is defined to last as long as that particular plugin instance is associated with a currently active page. A factory class shall be provided to obtain a reference to a VRML browser plugin in an implementation independent manner.
The browser shall also provide notification to the listening applications of when the world is no longer displayed on the page. When the browser is removed from visibility it shall generate a shutdown event to all registered listeners. If the browser becomes visible again an initialized event shall be generated. If a new page is loaded with a VRML browser as part of it, it will contain a different Browser reference and hence the applet will not receive any such notification of its presence.
Due to the nature of Java to native code interaction, it is possible that two instances of a Java class may refer to the same node or field inside the vrml scene (that is, using the == comparison will be false). For this reason, an identifier of a node or field cannot be implied to mean the same instance reference of the class representation. The representation of an Identifier in Java classes is implementation dependent. However, class instances may be checked for equivalence by calling the equals() method of the appropriate class. Implementations of the classes shall override the equals() method so that comparing two nodes, fields or other classes that require an identifier will return the correct result.
In the class structure, it is possible to associate user definable data references with each field of a node and with the node itself. If one reference to a node has data associated with it,, this information shall be available to all references to that node at all times. For example, if a field has data associated with it, is then disposed and a later application references that node, the data shall still remain (if that other application is Java based). There is no requirement to store this information if the node/field is no longer referenced by external applications or the internal scene graph, or if the external application is not Java based.
Java serialization may be used to either store the state of the scene graph (for example in a database or file) or communicate between two applications/applets interfacing with the same browser. Because serialization does not maintain the same Java reference, calls to the equals() method shall produce the correct result. The specification has not defined classes to be serializable. This is implementation dependent.
Due to the different environments that a Java based VRML may find itself in, this binding defines the following additional behaviour for Java implementations.
For standalone Java applications, the current working directory is determined by using the user.dir system property of the application. If a RURL is passed to the browser, it shall be resolved in equivalent terms to the following statements:
String url_base =
System.getProperty("user.dir");
String
complete_url = "file://" + url_base + <relative_url>
;
java.net.URL url =
new URL(complete_url);
The base document of the browser is considered to be the web page in which the browser is embedded if the VRML Browser does not have a VRML world loaded.
If the applet also creates a component-based VRML browser, the base document determination shall be treated in exactly the same manner as B.4.5.2 Java applications if there is not a base world already loaded. Note that this normally will produce different base documents if an applet accesses both a plugin and a component-based browser simultaneously.
If a browser is located remotely to the application using it (for example using an RMI implementation), the base url is considered to be the base URL of the world. If no world URL has yet been set, the appropriate action shall be either of the previous two sections depending on how the browser was started.
The Java null reference to an object shall be treated as the equivalent of the VRML NULL value. Where an SFNode field has its value set to null, this shall clear the field of the node reference causing the default behaviour defined by the parent node to be used for that field. When reading a value of an SFNode field where it is empty, the return value shall be null.
MFNodes are represented as an array of Node instances. It is possible that during the creation of the array some or all of contents may contain null references. How the browser treats a null reference is implementation dependent. That is, it is permissible to read back the field value and have it not contain the null node references, or to maintain them in the order they were sent.
In MF fields, arrays are used to represent the data contained in the VRML field. Setting the value of that field with an array of length 0 shall result in the contents of the field being cleared and is the equivalent of the VRML text file declaration of
SomeNode {
MFField
[]
}
An empty MF field shall return an array of length zero if queried about its value. The size() method of the MFField base class shall return a value of 0.
Attempting to set the value of the field with null shall generate an IllegalArgumentException.
MFField classes contain a set1Value() method for setting an individual value in the field.
If beginUpdate() has been called and multiple set1Value() methods have been called on that field, the result when endUpdate() is called shall be a single event with all of the individual values set. If two calls are made to set a particular array index, the last value written shall be used.
If beginUpdate()has not been called, the result shall be an event that contains the entire field value with the individual value changed. Multiple set1Value() calls to the field shall result in the equivalent number of events being generated inside the VRML browser.
Of particular concern to Java implementations is the disposal of resources used by the Java environment. The garbage collection environment creates problems when dealing with native code implementations of the VRML browser. An explicit dispose() method is provided with all classes representing VRML entities so that the application can explicitly dispose of the resources used by the browser implementation.
For safety purposes, where a class defines a dispose() method, it shall also override the default finalize() method provided by java.lang.Object and call the dispose() method. This shall ensure that even if the user has not explicitly called dispose on objects, when the object reference goes out of scope, all resources shall be freed regardless avoiding potential memory leaks.
Once a node has had the dispose method of, method calls on the node shall generate an InvalidNodeException.
vrml.eai.BrowserFactory
Creating a reference to a VRML browser must deal with a number of different scenarios: Java applet to VRML plugin in a web browser, server application talking to a browser on a separate machine or a component in a standalone Java application. Each of these requires a separate solution in order to maintain implementation dependence.
The method of access a VRML browser shall be through a single factory style class. This class contains methods for each type of access. To provide implementation independence the vrml.eai.BrowserFactoryImpl interface for the implementation dependent parts is defined. Browsers shall subclass this interface to provide the necessary dependent code. This interface is loaded by the vrml browser factory using dynamic methods or by having the code explicitly set.
A properties file called vrml.properties, if resident in the user's CLASSPATH shall be used to determine the name of the class to be loaded. The name of the property in the properties file shall be
vrml.eai.factory.class
which shall be set to the fully qualified name of the browser factory class implementation to be loaded. The implementation of this class shall not reside within the vrml.* class hierarchy but shall reside in the browser writer's own class hierarchy. The browser factory shall also contain a setBrowserFactoryImpl() method to allow an explicit setting of the factory implementation. If this method is the first method called of all the factory methods, it shall be used as the factory implementation. If any other method is called prior to calling this method, the name of the factory implementation shall be drawn from the properties file and loaded. Any attempt to call the set implementation method shall result in a vrml.eai.VrmlException being generated.
The factory implementation shall return the appropriate subclasses for each of the methods. If the implementation does not support the particular connection requested, it shall generate a vrml.eai.NotSupportedException. If it is supported, it shall return the appropriate subclass of the object for that method.
Browser
BrowserFactory.getBrowser(Applet)
Browser
BrowserFactory.getBrowser(Applet, String, int)
A browser that operates as part of a web browser requires a number of different parameters for correct determination of the plugin to access. Due to the nature of web pages, it is possible that an applet on one page may access either more that one VRML plugin or that the plugin exists in another HTML frame. The applet form of the getBrowser() method requires a reference to the accessing applet, the name of the frame and the index of the frame in the nominated frame. The frame name is a string representing the name of the frame. The index is the number of the VRML browser in the page (where there might be more than one) starting from 0.
Browser BrowserFactory.getBrowser(InetAddress, int)
An application server may wish to access browsers on client machines. The third variant of the getBrowser request requires an IP address (or machine name) and a port number. The server application requests the browser reference of the remote machine. Once the browser reference is returned, the server application may manipulate the browser contents like any other EAI using application.
The port number of the protocol may be any port number. There is no defined default port to which a browser will listen. The protocol between the application and the browser is also not defined.
VrmlComponent BrowserFactory.createVrmlComponent(String[])
The component browser is required to fit into the standard java.awt.Component model and is implemented as a subclass of vrml.eai.VrmlComponent. It shall derive from java.awt.Component and also provide a getBrowser() method that returns a reference to a standard vrml.eai.Browser object. The component implementation may implement the component in any manner it requires. Both lightweight components (all rendering performed in Java) and heavyweight components (with peer interfaces extending from java.awt.peer.ComponentPeer) are permitted. These details shall be hidden within the implementation specific classes and not accessible to the general API user.
The factory class shall include a method that generates an instance of this component class. Each call to the component shall result in a new independent instance of a VRML browser capable of running as a component. The browser shall be capable of running either within a web browser environment (e.g., Java applet window with a VRML browser in it) or in standalone applications with the restrictions appropriate to the underlying environment. It shall also use whatever hints are supported in the parameter argument passed to it. These hints are in the same form as those passed to loadURL.
String Browser.getName()
The name returned is a String representing the name of the browser. If this is not supported, null shall be returned.
String Browser.getVersion()
The version returned is a String representing the version number of the browser. If this is not supported, null shall be returned.
float Browser.getCurrentSpeed()
The speed value returned shall be a floating point number or 0.0 if is not supported.
float Browser.getCurrentFrameRate()
The frame rate value shall be a floating point number or 0.0 if it is not supported.
String Browser.getWorldURL()
The world URL shall be a string indicating the complete world URL as defined in 6.3.11 getWorldURL.
void Browser.replaceWorld(Node[])
The parameter shall be an array of Node instances which shall be used to replace the currently loaded world. If one or more of the node instances have been disposed of, an IllegalArgumentException shall be generated.
void Browser.loadURL(String[], String[])
The parameters shall be an array of strings for the URL list and an array of Strings for the parameters. If the browser determines that it cannot load any of the URLs passed, the browser event listener shall receive an event notifying it of an error.
If the parameters list is a zero length array or is null, the action is to replace the world in the current browser. The properties defined in Table B.6 are standard values that shall be supported.
Table B.6 — Property list for loadURL
Key |
Value |
Description of
Function |
replace |
true |
Replaces the entire page that browser is embedded in. If the browser is a standalone browser this shall have no effect. |
false |
The browser shall replace the contents of the currently loaded world with the new world specified by the URL argument. The same effect as providing no value to the parameters argument. |
|
target |
<frameName> |
The name of the frame shall be used to load the browser as the contents of the named HTML frame. |
Individual browser implementations may support extra property definitions.
void Browser.setDescription(String)
This service sets the description string of the browser. If the browser is running as a plugin, this shall set the title of the page (if the containing web browser supports this). For component browsers the result shall be implementation dependent.
Node[] Browser.createVrmlFromString(String)
The parameter shall be a string that contains legal syntax as defined in ISO/IEC 14772-1. The only difference is that the file header #VRML V2.0 utf8 need not be present as the first line in the string. If the string does not contain legal VRML97 syntax, an InvalidVrmlException shall be generated. Returned is an array of the top level Nodes in the order that they are declared in the string parameter.
void Browser.createVrmlFromURL(String[], Node, String)
The parameter list shall consist of an array of Strings describing the list of URLs, a reference to a destination Node and a String which is the name of the eventIn to send the loaded URL nodes to. If the browser determines that it cannot load any of the URLs passed, the browser event listener shall receive an event notifying it of an error.
void
Browser.addRoute(Node, String, Node, String)
void
Browser.deleteRoute(Node, String, Node, String)
This service is split into two separate methods: addRoute and deleteRoute. They both take the same argument list. The first parameter is a Node reference that the event will leave from. The second is a String describing the name of the eventOut. Third and forth parameters are the destination node reference and the eventIn as a String. If either of the Node references have been disposed of, an InvalidNodeException shall be generated. If either of the nodes do not contain the nominated eventIn/eventOut, an InvalidEventIn/EventOutException shall be generated appropriately.
void
Browser.beginUpdate()
void
Browser.endUpdate()
This service is split into two separate methods beginUpdate and endUpdate. The functionality remains as described in 6.3.16 Update Control.
void
Browser.addBrowserListener(BrowserListener)
void
Browser.removeBrowserListener(BrowserListener)
Registering interest in browser events is through a browser event listener. The listener is an interface which is passed browser events when the state of the browser changes or asynchronous error messages must be sent (for example, inability to load any of the requested URLs). Methods shall be provided to allow listeners to be added and removed dynamically. A separate event class shall be used to indicate the event information. This class has a predefined number of events although specific browser implementations may send more events than the defined values. The toString() method shall be overridden in this case to provide more information to the user in determining the extra event types to deal with them. Any extra event types must not have values below the figure defined by LAST_IDENTIFIER.
Node Browser.getNode(String)
The return value is a Node reference. The parameter is a String defining the DEF name of the required node. If the browser cannot find the node name, an InvalidNodeException shall be generated.
void Browser.dispose()
Dispose shall notify the browser that the Java implementation is no longer interested in the VRML browser. Any further requests to methods of this instance of the browser interface shall generate an InvalidBrowserException.
vrml.eai.Node
The ability to list all of the fields of a node reference and their values is not available as part of the standard implementation. It is not possible to get the name of the node. The implementation of the node services is implemented as the class vrml.eai.Node.
String Node.getType()
The 6.4.5 getType and 6.4.4 getName services are combined into a single method request getType() that returns the name of the node as a String.
EventIn
Node.getEventIn(String)
EventOut
Node.getEventOut(String)
6.4.3 getField service is implemented as two separate methods getEventIn() and getEventOut() which allows access to eventIns and eventOuts but not to fields. An exposedField may be accessed as either the eventIn or eventOut portion separately through these two methods. The normal field name or with the set_ modifier may be used with the getEventIn method. The normal field name or the _changed modifier may be used with the getEventOut method.
void Node.dispose()
Dispose shall notify the browser that the Java implementation is no longer interested in this node instance and it is free to do as required with the node representation. Any further requests to methods of this instance of the node reference shall generate an InvalidNodeException. If two separate instances of the same class represent the same node (as defined by the equals() method returning true) and one has dispose called, this shall not effect the other instance.
vrml.eai.field
package
vrml.eai.field.BaseField
and subclasses.
The Java implementation of the field services does not directly follow the model outlined in 6.5 Field Services. Instead, it makes heavy use of the Object Oriented nature of Java to provide directly the capabilities suggested by the services specified. All the services are implemented in the classes provided in the vrml.eai.field package.
The following outlines how the Java binding conforms to the requirements of the EAI.
6.5.2 getAccessType is not a directly callable method in the Java implementation. The access type is implied by the class that represents the field. For example, calling
EventIn trans = some_transform.getEventIn("set_translation");
will return an EventIn class reference. From this the implication is that the access type of this field is an eventIn.
int BaseField.getType()
The getType() method of vrml.eai.field.BaseField returns an identifier of the type of field that the instance of the class represents. The list of legal type identifiers is included as public final variables in the class. The return value of the getType() method shall be one of these values.
The class instance is also used as an alternative type of representation of the node type. There shall be one class for each type of VRML field, one derived from EventIn and one derived from EventOut. The class reference returned from a call to Node.getEventIn() or Node.getEventOut() shall return an instance of one of these classes respectively.
The 6.5.3 getName service is not supported by the Java language bindings
The getValue() method of vrml.eai.field.BaseField is supported only on classes derived from eventOut. It is not possible to read values from eventIn as there is no method to support this operation. On fields which are exposedFields, an eventOut derived class will be needed to access the field to read its value.
The getValue() method returns values in a format appropriate to the individual field type. If the method returns an array of values, the array shall be guaranteed to be created on each call. The implementation shall not reuse return value references between calls to the methods. This is to guarantee thread-safe data integrity.
To provide similarity to ISO/IEC 14772-1 B Java platform scripting reference, a get1Value() method is provided for MF fields. This allows access to a single value out of the many values. When an attempt is made to access a value at an index greater than the number of items in that eventOut, a java.lang.ArrayIndexOutOfBoundsException shall be generated. Each time the getValue() method is called, a new instance of the returned array shall be generated.
An alternate form of the getValue()and get1Value() methods shall be available for the MF eventOuts. These forms shall take arrays as parameters that can be used to write values in. See the javadoc outline of each class for proper definitions of what methods are to be provided.
The setValue() method of vrml.eai.field.BaseField is supported only on classes derived from EventIn. It is not possible to write values from eventIn as there is no method to support this operation. On fields which are exposedFields, an EventIn derived class will be needed to write a new value.
To provide similarity with ISO/IEC 14772-1 B Java platform scripting reference, a set1Value() method is provided for MFFields. This allows the ability to change a single value of a field without having to re-create the entire array of values. When an attempt is made to set a value at an index greater than the number of items in that eventIn, a java.lang.ArrayIndexOutOfBoundsException shall be generated. See B.4.6.4 set1Value for other behavioural aspects of this method.
void
EventOut.addVrmlEventListener(VrmlEventListener)
void
EventOut.removeVrmlEventListener(VrmlEventListener)
The shall be no capabilities to attach listeners to eventIns. Listening to eventOuts is available. This restriction is implemented as part of the Java API implementation which has separate classes for eventIn and eventOut representation. Where a field is declared to be an exposedField, listeners can only be attached to the eventOut portion.
vrml.eai.Browser
vrml.eai.BrowserFactory
vrml.eai.BrowserFactoryImpl
vrml.eai.VrmlComponent
vrml.eai.NoSuchBrowserException
vrml.eai.NotSupportedException
java.net.UnknownHostException
vrml.eai.Browser
vrml.eai.Node
vrml.eai.event.BrowserListener
vrml.eai.event.BrowserEvent
vrml.eai.InvalidBrowserException
vrml.eai.InvalidVrmlException
vrml.eai.InvalidNodeException
vrml.eai.InvalidURLException
vrml.eai.URLUnavailableException
vrml.eai.field.InvalidEventInException
vrml.eai.field.InvalidEventOutException
vrml.eai.Node
vrml.eai.field.EventOut
vrml.eai.field.EventIn
vrml.eai.InvalidNodeException
vrml.eai.field.InvalidEventInException
vrml.eai.field.InvalidEventOutException
vrml.eai.field.BaseField
vrml.eai.field.EventIn
vrml.eai.field.EventInMFColor
vrml.eai.field.EventInMFFloat
vrml.eai.field.EventInMFInt32
vrml.eai.field.EventInMFNode
vrml.eai.field.EventInMFRotation
vrml.eai.field.EventInMFString
vrml.eai.field.EventInMFTime
vrml.eai.field.EventInMFVec2f
vrml.eai.field.EventInMFVec3f
vrml.eai.field.EventInSFBool
vrml.eai.field.EventInSFColor
vrml.eai.field.EventInSFFloat
vrml.eai.field.EventInSFImage
vrml.eai.field.EventInSFInt32
vrml.eai.field.EventInSFNode
vrml.eai.field.EventInSFRotation
vrml.eai.field.EventInSFString
vrml.eai.field.EventInSFTime
vrml.eai.field.EventInSFVec2f
vrml.eai.field.EventInSFVec3f
vrml.eai.field.EventOut
vrml.eai.field.EventOutMField
vrml.eai.field.EventOutMFColor
vrml.eai.field.EventOutMFFloat
vrml.eai.field.EventOutMFInt32
vrml.eai.field.EventOutMFNode
vrml.eai.field.EventOutMFRotation
vrml.eai.field.EventOutMFString
vrml.eai.field.EventOutMFTime
vrml.eai.field.EventOutMFVec2f
vrml.eai.field.EventOutMFVec3f
vrml.eai.field.EventOutSFBool
vrml.eai.field.EventOutSFColor
vrml.eai.field.EventOutSFFloat
vrml.eai.field.EventOutSFInt32
vrml.eai.field.EventOutSFNode
vrml.eai.field.EventOutSFRotation
vrml.eai.field.EventOutSFString
vrml.eai.field.EventOutSFTime
vrml.eai.field.EventOutSFVec2f
vrml.eai.field.EventOutSFVec3f
vrml.eai.event.VrmlEvent
vrml.eai.event.VrmlEventListener
vrml.eai.field.InvalidFieldException
vrml.eai.field.InvalidEventInException
vrml.eai.field.InvalidEventOutException
Package vrml.eai
+- vrml.eai.Browser
+- vrml.eai.BrowserFactory
+- vrml.eai.Node
+- vrml.eai.BrowserFactoryImpl
+- vrml.eai.VrmlComponent
+- vrml.eai.VrmlException
+- vrml.eai.InvalidBrowserException
+- vrml.eai.InvalidVrmlException
+- vrml.eai.InvalidNodeException
+- vrml.eai.InvalidURLException
+- vrml.eai.NoSuchBrowserException
+- vrml.eai.NotSupportedException
+- vrml.eai.URLUnavailableException
Package vrml.eai.event
+- vrml.eai.event.BrowserListener
+- vrml.eai.event.BrowserEvent
+- vrml.eai.event.VrmlEvent
+- vrml.eai.event.VrmlEventListener
Package vrml.eai.field
+- vrml.eai.field.BaseField
+- vrml.eai.field.EventIn
| +- vrml.eai.field.EventInMFColor
| +- vrml.eai.field.EventInMFFloat
| +- vrml.eai.field.EventInMFInt32
| +- vrml.eai.field.EventInMFNode
| +- vrml.eai.field.EventInMFRotation
| +- vrml.eai.field.EventInMFString
| +- vrml.eai.field.EventInMFTime
| +- vrml.eai.field.EventInMFVec2f
| +- vrml.eai.field.EventInMFVec3f
| +- vrml.eai.field.EventInSFBool
| +- vrml.eai.field.EventInSFColor
| +- vrml.eai.field.EventInSFFloat
| +- vrml.eai.field.EventInSFImage
| +- vrml.eai.field.EventInSFInt32
| +- vrml.eai.field.EventInSFNode
| +- vrml.eai.field.EventInSFRotation
| +- vrml.eai.field.EventInSFString
| +- vrml.eai.field.EventInSFTime
| +- vrml.eai.field.EventInSFVec2f
| +- vrml.eai.field.EventInSFVec3f
+- vrml.eai.field.EventOut
+- vrml.eai.field.EventOutMField
+- vrml.eai.field.EventOutMFColor
+- vrml.eai.field.EventOutMFFloat
+- vrml.eai.field.EventOutMFInt32
+- vrml.eai.field.EventOutMFNode
+- vrml.eai.field.EventOutMFRotation
+- vrml.eai.field.EventOutMFString
+- vrml.eai.field.EventOutMFTime
+- vrml.eai.field.EventOutMFVec2f
+- vrml.eai.field.EventOutMFVec3f
+- vrml.eai.field.EventOutSFBool
+- vrml.eai.field.EventOutSFColor
+- vrml.eai.field.EventOutSFFloat
+- vrml.eai.field.EventOutSFInt32
+- vrml.eai.field.EventOutSFNode
+- vrml.eai.field.EventOutSFRotation
+- vrml.eai.field.EventOutSFString
+- vrml.eai.field.EventOutSFTime
+- vrml.eai.field.EventOutSFVec2f
+- vrml.eai.field.EventOutSFVec3f
+- vrml.eai.VrmlException
+- vrml.eai.field.FieldException
+- vrml.eai.field.InvalidEventInException
+- vrml.eai.field.InvalidEventOutException
The following is an example Java EAI script that finds a Material node called BoxMaterial in the scene graph and changes its diffuseColor field to be 0 1 0. This has the effect of changing the box from its original red color to green. To view this example within a web browser, the following HTML segment is used.
<embed src="box.wrl" height="300" width="300">
<applet code="box.class" mayscript height="1" width="1">
</applet>
box.wrl
#VRML V2.0 utf8
Shape {
appearance Appearance {
material DEF BoxMaterial Material {
diffuseColor 1 0 0
}
}
geometry Box { size 2 2 2 }
}
box.java
import java.applet.*;
import vrml.eai.field.*;
import vrml.eai.Node;
import vrml.eai.BrowserFactory;
import vrml.eai.Browser;
public class box extends Applet {
public void init() {
super.init();
}
public void start() {
Browser browser = null;
Node material = null;
EventInSFColor boxcolor = null;
// Get the VRML Browser - try 10 times
for (int count = 0; count < 10; count++) {
browser = BrowserFactory.getBrowser(this);
if (browser != null) break;
try {
Thread.sleep(200);
} catch (InterruptedException ignored) {}
}
// Get the diffuseColor eventIn of the DEF'd material node
try {
material = browser.getNode("BoxMaterial");
boxcolor = (EventInSFColor) material.getEventIn("set_diffuseColor");
} catch (vrml.eai.InvalidNodeException ignored) {}
// Sleep for 1 second
try {
Thread.sleep(1000);
} catch ( InterruptedException ignored ) {}
// Change the material's diffuse color to green (0,1,0)
float[] newcolor = new float[3];
newcolor[0] = 0.0f; newcolor[1] = 1.0f; newcolor[2] = 0.0f;
boxcolor.setValue(newcolor);
}
}
The next example shows how to create new geometry and add this to an existing scene using the EAI. In this case, the VRML file contains a red cuboid and the EAI script creates and overlays a blue sphere. The HTML segment for embedding this example in a web browser is as follows.
<embed src="create.wrl" height="300" width="300">
<applet code="create.class" mayscript height="1" width="1">
</applet>
create.wrl
#VRML V2.0 utf8
DEF NewNode Group {}
Shape {
appearance Appearance {
material DEF BoxMaterial Material {
diffuseColor 1 0 0
}
}
geometry Box { size 2 2 1 }
}
create.java
import java.applet.*;
import vrml.eai.field.*;
import vrml.eai.Node;
import vrml.eai.BrowserFactory;
import vrml.eai.Browser;
public class create extends Applet {
public void init() {
super.init();
}
public void start() {
Browser browser = null;
Node rootnode = null;
EventInMFNode children = null;
// Get the VRML Browser - try 10 times
for (int count = 0; count < 10; count++) {
browser = BrowserFactory.getBrowser(this);
if (browser != null) break;
try { Thread.sleep(200); } catch (InterruptedException e) {}
}
// Get the set_children eventIn of the DEF'd Group node
try {
rootnode = browser.getNode("NewNode");
children = (EventInMFNode) rootnode.getEventIn("set_children");
} catch (vrml.eai.InvalidNodeException ignored) {}
// Create a new blue Sphere Shape node
String newvrml =
"#VRML V2.0 utf8\nShape { appearance Appearance { material " +
"Material { diffuseColor 0 0 1 } } geometry Sphere { radius 1 } }";
// Create and add the new node to the scene graph
children.setValue( browser.createVrmlFromString( newvrml ) );
}
}
This example illustrates cycling between different cameras in a scene using the EAI. The VRML file contains a yellow cone with three Viewpoint nodes specified. The EAI script then continually binds each viewpoint in succession with a 1 second delay between each switch. The HTML segment for embedding this example in a web browser is as follows.
<embed src="viewswitch.wrl" height="300" width="300">
<applet code="viewswitch.class" mayscript height="1" width="1">
</applet>
viewswitch.wrl
#VRML V2.0 utf8
DEF View1 Viewpoint {
position 0 -3 6
orientation 1 0 0 0.46
description "Viewpoint 1"
}
DEF View2 Viewpoint {
position 0 7 0
orientation 0 -.707 -.707 3.1416
description "Viewpoint 2"
}
DEF View3 Viewpoint {
position 0 0 10
orientation 0 0 1 0
description "Viewpoint 3"
}
Shape {
appearance Appearance {
material DEF BoxMaterial Material {
diffuseColor 1 1 0
}
}
geometry Cone {}
}
viewswitch.java
import java.applet.*;
import vrml.eai.field.*;
import vrml.eai.Node;
import vrml.eai.BrowserFactory;
import vrml.eai.Browser;
public class viewswitch extends Applet {
public void init() {
super.init();
}
public void start() {
Browser browser = null;
EventInSFBool bind1 = null;
EventInSFBool bind2 = null;
EventInSFBool bind3 = null;
// Get the VRML Browser - try 10 times
for (int count = 0; count < 10; count++) {
browser = BrowserFactory.getBrowser(this);
if (browser != null) break;
try { Thread.sleep(200); } catch (InterruptedException e) {}
}
// Get the set_bind eventIns for the three DEF'd Viewpoint nodes
try {
Node view1 = browser.getNode("View1");
Node view2 = browser.getNode("View2");
Node view3 = browser.getNode("View3");
bind1 = (EventInSFBool) view1.getEventIn("set_bind");
bind2 = (EventInSFBool) view2.getEventIn("set_bind");
bind3 = (EventInSFBool) view3.getEventIn("set_bind");
} catch (vrml.eai.InvalidNodeException ignored) {}
// cycle through each Viewpoint node at 1 sec intervals
while (true) {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
bind1.setValue(true);
try { Thread.sleep(1000); } catch (InterruptedException e) {}
bind2.setValue(true);
try { Thread.sleep(1000); } catch (InterruptedException e) {}
bind3.setValue(true);
}
}
}
This next example shows how to perform scene graph traverals using the EAI. The script will search for all Switch nodes in a scene and set their whichChoice fields to a certain value. Two buttons are created in the applet's canvas to let the user set all Switch nodes to their first or second nodes. For the particular VRML file show here, this causes a switch between a purple cube and a cyan sphere. Note that we use the beginUpdate() and endUpdate() browser methods so that the scene graph is only updated once the traversal process has completed.
<APPLET CODE="switcher.class" HEIGHT="32" WIDTH="400" MAYSCRIPT>
</APPLET>
<EMBED SRC="switcher.wrl" WIDTH="400" HEIGHT="400">
switcher.wrl
#VRML V2.0 utf8
DEF RootNode Group {
children [
NavigationInfo { type [ "EXAMINE", "ANY" ] }
Switch {
whichChoice 0
choice [
Shape { # Switch 1
appearance Appearance { material
Material { diffuseColor 1 0 1 }
}
geometry Box { size 4 4 4 }
}
Shape { # Switch 2
appearance Appearance { material
Material { diffuseColor 0 1 1 }
}
geometry Sphere { radius 2 }
}
]
}
]
}
switcher.java
import java.awt.*;
import java.applet.*;
import vrml.eai.Node;
import vrml.eai.BrowserFactory;
import vrml.eai.Browser;
import vrml.eai.field.*;
public class switcher extends Applet {
Browser browser = null;
String button1 = "Flick Switch 1";
String button2 = "Flick Switch 2";
// create the two applet buttons and get the browser reference
public void start() {
setBackground(Color.white);
add(new Button(button1));
add(new Button(button2));
browser = BrowserFactory.getBrowser(this);
}
// search scene graph for all Switch nodes and update their whichChoice
public void set_switch(int value) {
browser.beginUpdate();
Node root = browser.getNode("RootNode");
set_switch_recur((EventOutMFNode) root.getEventOut("children"), value);
browser.endUpdate();
}
// recursive method to do the scene graph traversal
public void set_switch_recur(EventOutMFNode children, int value) {
if (children == null) return;
Node nodes[] = children.getValue();
int num_nodes = nodes.length;
for (int i = 0; i < num_nodes; ++i) {
String node_type = nodes[i].getType();
if (node_type.compareTo("Switch") == 0) {
// Grab the whichChoice field of the Switch and change it
EventInSFInt32 whichChoice = (EventInSFInt32)
nodes[i].getEventIn("whichChoice");
whichChoice.setValue(value);
} else if (node_type.compareTo("Group") == 0 ||
node_type.compareTo("Transform") == 0 ||
node_type.compareTo("Collision") == 0) {
// recurse into grouping nodes - other grouping nodes possible
set_switch_recur((EventOutMFNode) nodes[i].getEventOut("children"),
value);
}
}
}
// The button event handling routine
public boolean action(Event event, Object what) {
if (event.target instanceof Button && browser != null) {
Button b = (Button) event.target;
if (b.getLabel() == button1) {
set_switch(0);
} else if (b.getLabel() == button2) {
set_switch(1);
}
}
return true;
}
}
This final example shows the creation of widgets in a Java applet that can be used to control items in the scene graph. Here the EAI is used to build a helix model using an Extrusion node and to animate this model. The applet then allows the user to change the number of coils in the helix. The HTML segment for embedding this example in a web browser is as follows.
<embed src="helix.wrl" border=0 height="200" width="200">
<applet code="helix.class" mayscript height="100" width="200">
</applet>
helix.wrl
#VRML V2.0 utf8
Viewpoint {
position 0 4 5
orientation 1 0 0 -0.5
}
Shape {
appearance Appearance {
material Material {
diffuseColor 0.8 0.8 0.9
shininess 1
}
}
geometry DEF Coil Extrusion {
crossSection []
spine []
creaseAngle 3.14
}
}
helix.java
import java.awt.*;
import java.applet.*;
import vrml.eai.field.*;
import vrml.eai.Node;
import vrml.eai.BrowserFactory;
import vrml.eai.Browser;
public class helix extends Applet implements Runnable {
EventInMFVec3f spine = null;
EventInMFVec2f crossSection = null;
Thread thread = null;
Choice choice;
int spineLimit = 250;
float[][] spineValue = new float[spineLimit+1][3];
int crossSectionLimit = 10;
float[][] crossSectionValue = new float[crossSectionLimit+1][2];
float numCoils = 5f;
// set up the applet controls
public void init() {
super.init();
setBackground(Color.white);
Panel p1 = new Panel();
Label lblNCoils = new Label("Number of Coils");
p1.add(lblNCoils);
choice= new Choice();
choice.addItem("5"); choice.addItem("4"); choice.addItem("3");
choice.addItem("2"); choice.addItem("1");
p1.add(choice);
add(p1);
}
public void start() {
// get the VRML Browser reference
Browser browser = null;
for (int count = 0; count < 10; count++) {
browser = BrowserFactory.getBrowser(this);
if (browser != null) break;
try { Thread.sleep (200); } catch (InterruptedException e) {}
}
if (browser == null) {
throw new Error("Failed to get the browser after 10 tries!");
}
// get the spine and crossSection fields of the Extrusion node
try {
Node coil = browser.getNode("Coil");
spine = (EventInMFVec3f) coil.getEventIn("set_spine");
crossSection = (EventInMFVec2f) coil.getEventIn("set_crossSection");
} catch (vrml.eai.InvalidNodeException ne){
System.out.println("Node Exception Error:" + ne.getMessage());
}
if (thread == null) {
thread = new Thread(this);
thread.start();
} else
thread.resume();
}
public void stop() {
if (thread != null) thread.suspend();
}
public void destroy() {
thread.stop();
thread = null;
}
public void run() {
// calculate and set the crossSection values of the Extrusion node
float thickness = 0.1f;
float diameter = 1.5f;
float two_pi = (float) Math.PI * 2.0f;
for (int j = 0; j <= crossSectionLimit; j++) {
float angle = j * two_pi / crossSectionLimit;
crossSectionValue[j][0] = thickness / 2 * (float) Math.sin(angle);
crossSectionValue[j][1] = thickness / 2 * (float) Math.cos(angle);
}
crossSection.setValue(crossSectionValue);
// oscilate the spring between 0.3 and 1, with 0.05 increments
float inc = 0.05f;
float value = 0.3f;
float springLength = 2f;
while (true) {
value += inc;
//calculate and set the coordinates for the whole spine
for (int i = 0; i <= spineLimit; i++) {
float stepsPerCoil = (float) Math.round(spineLimit / numCoils);
float angle = i * two_pi / stepsPerCoil;
spineValue[i][0] = diameter / 2 * (float) Math.cos(angle);
spineValue[i][1] = springLength / numCoils * value * i / stepsPerCoil;
spineValue[i][2] = diameter / 2 * (float) Math.sin(angle);
}
spine.setValue(spineValue);
// sleep for 0.1 seconds
try { thread.sleep(100); } catch (InterruptedException e) {}
// reverse movement direction
if (value >= 1f && inc == 0.05f)
inc = -0.05f;
else if (value <= 0.3 && inc == -0.05f)
inc = 0.05f;
}
}
// handle input (deprecated Java API)
public boolean handleEvent(Event event) {
if (event.id == Event.ACTION_EVENT && event.target == choice)
changeNumCoils();
return super.handleEvent(event);
}
// changes number of coils in the helix
private void changeNumCoils() {
String number = choice.getSelectedItem();
numCoils = (new Float(number)).floatValue();
}
}