The Source for Java Technology Collaboration


Home | Changes | Index | Search | Go

Back to Documentation Page

Applications Development Tips

Table of Contents

Component3D?

Component3D? provide the following features 1) Animation of a itself and all it's children 2) setVisible controls

When writing LG3D? applications use Component3D? to group and animate portions of the scene graph. If you don't need animation or the setVisible controls consider using other scene graph Nodes such as BranchGroup?, TransformGroup? or Switch node to obtain the desired visual effect. This will improve performance.

Transparency

If you don't actually use Transparency in your application then don't add TransparencyAttributes? to the Appearance bundles. If you are using Transparency try to share TransparencyAttributes? as much as possible.

Lg standards way of logging things :

looking glass redirects all logging in the lgserver.log file. In order for your program to outputs some things in this file, you first need to declare a variable like this :

import static java.util.logging.Level.*;
import java.util.logging.Logger;
 
private static Logger logger = Logger.getLogger("lg.my_app_name");

(Where my_app_name must be replaced by the real application name)

And now if you wants to log something in the lgserver.log file just do this :

logger.log(Level.INFO,"Some infos"); 

or

logger.log(Level.SEVERE,"Some infos on a severe error");

the possible values of Level are :

  • SEVERE (highest value)
  • WARNING
  • INFO
  • CONFIG
  • FINE
  • FINER
  • FINEST (lowest value)

Including Java3D objects in a lg3d program

If you want to include java3D pieces in a lg3d application here is how to do it :

Frame3D frame = new Frame3D();
Java3DGraph j3dwrap = new Java3DGraph();
BranchGroup objRoot = new BranchGroup();
/*
Here you add Java3D objects to the BranchGroup
*/
j3dwrap.addJ3dChild(objRoot);
frame.addChild(j3dwrap);

Java3DGraph? is a class that extends Component3D? so you can use all the methods of Component3D? class on a Java3DGraph? for example you could have done : j3dwrap.setTranslation(x,y,z); to move the Java3D object somewhere in the scene.

here is a link to the Javadoc of Java3DGraph?.

Dynamically showing/hiding objects in a scene based on a visiblity mask

First of all you need to Define the visibility mask :

int size = 10;
BitSet visibilityMask = new BitSet(size); //this initialise the mask to have a 10 values initilized to false
visibilityMask.set(3); //we set the 3rd entry to true (= visible in our case)
visibilityMask.set(5); //we set the 5th entry to true (= visible in our case)

Now we can build the scene that will use this BitSet? as mask :

Frame3D frame = new Frame3D(); // a common lg3d Frame3D object
SimpleAppearance itemApp = new SimpleAppearance(0.0f,0.5f,0.0f,0.5f); //a green transparent appearance
Java3DGraph j3dwrap = new Java3DGraph(); //a java3d graph wrapper (see other examples on this page)

BranchGroup objRoot = new BranchGroup(); //a common java3d branchGroup
        
Switch switchNode = new Switch(Switch.CHILD_MASK); //we declare the switch node so that it use a Mask to decide which of its childrens are visible or not
switchNode.setChildMask(visibilityMask); //we give the BitSet we declared before as the visibility mask
switchNode.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE); //needed to say that we will modify the switchNode even after it has been included in the SceneGraph (see Java3D docs)
switchNode.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
 
for (int x=0;x<size;x++) {
   TransformGroup tg = new TransformGroup(); //a new Java3D TransformGroup (see java3D tutorials)

   Box b = new Box(width,height,depth,Box.GENERATE_NORMALS,itemApp); // a lg3d Shape.Box
   tg.addChild((javax.media.j3d.Node) b.getWrapped().getWrapped()); //Here we add a lg3d object in the java3D sceneGraph Branch
                        
   Vector3f v = new Vector3f(((x * width),0.0f,0.0f);
 

   Transform3D t3d = new Transform3D(); 
   t3d.setTranslation(v);                        
   tg.setTransform(t); //we move the box to a certain place
 
   switchNode.addChild(a); //we add the TransformGroup to the switch node
}
objRoot.addChild(switchNode);
j3dwrap.addJ3dChild(objRoot);
j3dwrap.setTranslation(x1,y1,z1); //we move all the objects somewhere

frame.addChild(j3dwrap);
frame.changeEnabled(true);
frame.changeVisible(true); 

This code will show 2 boxes (the 3rd and the 5th box). If we now do

BitSet visibilityMask2 = new BitSet(size);
visibilityMask2.set(1);
visibilityMask2.set(3);
visibilityMask2.set(5);
visibilityMask2.set(7);
visibilityMask2.set(9);
switchNode.setChildMask(visibilityMask2);

We will now see 5 boxes on the screen (the 1st,3rd,5th,7th and 9th box)

Of course we can do this at runtime to fastly change which objects of our list are visible and which are not.

here is a link to the javadoc page of the BitSet? class
here is a link to the javadoc page of java3d Switch class
here is a page with good Java3d's tutorials

Using a xml file as configuration file for your application

First of all we need to define a class that will describe the content of the xml config file. This class must implements the "Serializable" interface. It must have a variable for each value you want to be in the config file as well as getters and setters for this variable, An example would be :

import java.io.*;
import java.util.*;
 
public class MyConfig implements Serializable {

   float configValue1; 
   String configValue2;
 
   MyConfig() {}  //empty constructor
 
   public float getConfigValue1() {
      return configValue1;
   }
   
   public void setConfigValue1(float x) {
      configValue1 = x;
   }

   public String getConfigValue2() {
      return configValue2;
   }

   public void setConfigValue2(String v) {
      configValue2 = v.clone();
   }
}

Now we must write a function that will reads the config file if it exists and create it with default value if it doesn't exist. It could be done like this :

private void getMyConfig throws FileNotFoundException {

 
   cfg = new Myconfig(); //an instance of the class defined just before
   URL url = getClass().getClassLoader().getResource("org/jdesktop/lg3d/apps/your_application/your_config_file.xml"); // the path to the xml file (don't forget to replace your_application/your_config_file.xml by the real values)
   File f = new File(url); //we try to open the file

 
   if (f.exists()) { //if the file exists we just read it
      XMLDecoder rdr = new XMLDecoder(
                        new BufferedInputStream(
                        new FileInputStream(f)));
                
      cfg = (MyConfig)rdr.readObject(); //here we actually reads the xml file

      rdr.close();
   } else { //if the file doesn't exists we must create it with default values ...
      cfg.setConfigValue1(1.0f); //some float value
      cfg.setConfigValue2(new String("bla bla bla")); //some string value

      //now we must write the default config file :      
      XMLEncoder wtr = new XMLEncoder(
                new BufferedOutputStream(
                new FileOutputStream(url)));
      
      //here we try to modify the permissions on the file ( linux / unix related )    
      try {

         Runtime.getRuntime().exec("/bin/chmod 666 "+ url.toString() );
      } catch(Exception runtimeE) {
         logger.warning("Unable to set permissions on MyConfig.xml");
      }
            
      wtr.writeObject(cfg); //here we actually write the file

      wtr.close();
      
      //And now we read it just to see if everything went Ok ..
 
      XMLDecoder rdr = new XMLDecoder(
         new BufferedInputStream(
         new FileInputStream(url)));
                
      gcfg = (MyConfig)rdr.readObject();
      rdr.close();
 

   }
}

In addition to this you will need this 2 variables declared in the class that contains the getMyConfig() function :

private MyConfig cfg;
private static Logger logger = Logger.getLogger("lg.myApplication");

And you will need theses imports in the file that contains the class :

import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;

In brief :

  1. declare a class that implements serializable interface
  2. make a function that read/write the files
  3. call this function from somewhere at the start of your program
  4. access the values in the config file like this : cfg.get_Value_Name();

Of course you can have other types than String and float in your config file. The advantage of using a xml config file is that after it has been created (normally after the first launch of your program), the user will be able to modify the values in the config file to fit his preferences (so don't put any critical value in this file, or just do some checking on the values read from the config file)

here you can find the javadocs of the Serializable interface.

Topic AppDevelopmentTips . { Edit | Ref-By | Printable | Diffs r9 < r8 < r7 < r6 < r5 | More }
 XML java.net RSS

Revision r9 - 08 Oct 2007 - 11:24:56 - Main.rkd
Parents: WebHome > ProjectLookingGlass