Home | Examples | Supported Classes | Collections | What about MyClass | Documentation | Download Latest Release | SourceForge Project Page | SVN code
▲ Top

A Simple Example▲ Top

This is a typical example found in many Java programs. There exists a property that defines the dimensions of let's say a window in the following format:

# For example 150;20
window.dimension = width;height

What a Java developer had to do so far was:

import java.awt.Dimension;
import java.io.FileReader;
import java.util.Properties;

/**
*
@author Savvas Dalkitsis
*/
public class Test {
 
public static void main(String[] args) {

   
try {
     
Properties p = new Properties();
      p.load
(new FileReader("program.properties"));

      String dim = p.getProperty
("window.dimension");
      String
[] dimA = dim.split(";");
     
if (dimA.length == 2) {
       
try {
         
int w = Integer.parseInt(dimA[0]);
         
int h = Integer.parseInt(dimA[1]);
          Dimension d =
new Dimension(w, h);

         
// Do something with the dimension
       
} catch (NumberFormatException e) {
         
e.printStackTrace();
       
}
      }
else {
       
System.err.println("Error parsing the property");
     
}
    }
catch (Exception e) {
     
e.printStackTrace();
   
}
  }

}

With Joperties, all the developer needs to do is this:

import java.awt.Dimension;
import java.io.FileReader;

import joperties.Joperties;
import joperties.exceptions.InterpretationException;
import joperties.exceptions.NoApropriateInterpeterFoundException;

/**
*
@author Savvas Dalkitsis
*/
public class Test {
 
public static void main(String[] args) {
   
try {
     
Joperties p = new Joperties();
      p.load
(new FileReader("program.properties"));

      Dimension d = p.getJoperty
("window.dimension", Dimension.class);
     
// Do something with the dimension.
   
} catch (NoApropriateInterpeterFoundException e) {
     
e.printStackTrace();
   
} catch (InterpretationException e) {
     
e.printStackTrace();
   
} catch (Exception e) { // IOExceptions, not Joperties related.
     
e.printStackTrace();
   
}
  }

}

As you can see, the user has transformed a 13 line piece of code to 5 lines and if you exclude the error handling, a 5 line piece of code to a single line! And this was a very simple example. With Joperties you can save and restore a big list of Classes including Collections of them (for instance a LinkedList of type Polygon). As you can imagine, writing and maintaining code for conversion of so many classes can be cumbersome and error prone. This is where Joperties shows its use.

▲ Top

A More Involved Example▲ Top

Some data types can be described by compositing other types. One such example is a GradientPaint. It consist of 2 points (the start and end point of the gradient), 2 colors (the start and end colors) and a boolean (denoting if the gradient is cyclical). The following code:

import java.awt.Color;
import java.awt.GradientPaint;

import joperties.Joperties;
import joperties.exceptions.EncodingException;
import joperties.exceptions.NoApropriateInterpeterFoundException;

/**
*
@author Savvas Dalkitsis
*/
public class Test {
 
public static void main(String[] args) {
   
try {
     
Joperties p = new Joperties();
      GradientPaint grad =
new GradientPaint(0, 0, Color.RED, 100, 150,
          Color.CYAN,
true);
      p.setJoperty
("sample.gradient", grad);
      System.out.println
(p.getProperty("sample.gradient"));
   
} catch (NoApropriateInterpeterFoundException e) {
     
e.printStackTrace();
   
} catch (EncodingException e) {
     
e.printStackTrace();
   
}
  }

}

Produces this output:

0.0;0.0|0xff0000|100.0;150.0|0x00ffff|true

As you can see, this example also demonstrates another quality already discussed about Joperties. A Joperties object is a Properties object. So when we set a Joperty, we can see the encoded format of the object by getting the Property with the same key.

▲ Top

A Complicated Example▲ Top

Joperties also works with the Collections framework. Because classes in the Collection framework are generic, and because in Java the type of generic classes is erased during runtime, a special syntax is required when dealing with them. Let's assume you want to set a list of Points as a property. This code is used to set a Collection:

import interpreters.CollectionInterpreter;

import java.awt.Point;
import java.util.LinkedList;
import java.util.List;

import joperties.Joperties;
import joperties.exceptions.EncodingException;
import joperties.exceptions.NoApropriateInterpeterFoundException;

/**
*
@author Savvas Dalkitsis
*/
public class Test {
 
public static void main(String[] args) {
   
try {
     
Joperties p = new Joperties();
      List<Point> points =
new LinkedList<Point>();
      points.add
(new Point(0, 0));
      points.add
(new Point(50, 20));
      points.add
(new Point(50, 50));
      points.add
(new Point(100, 100));
      p.setJoperty
("list.points", points,
         
new CollectionInterpreter<Point>(Point.class));
      System.out.println
(p.getProperty("list.points"));
   
} catch (NoApropriateInterpeterFoundException e) {
     
e.printStackTrace();
   
} catch (EncodingException e) {
     
e.printStackTrace();
   
}
  }

}

This is the output:

0;0>>50;20>>50;50>>100;100

To get the object from the property, we also use a different syntax:

import java.awt.Point;
import java.util.Collection;

import joperties.Joperties;
import joperties.exceptions.InterpretationException;
import joperties.exceptions.NoApropriateInterpeterFoundException;
import joperties.interpreters.CollectionInterpreter;

/**
*
@author Savvas Dalkitsis
*/
public class Test {
 
public static void main(String[] args) {
   
try {
     
Joperties p = new Joperties();
      p.setProperty
("list.points", "0;0>>50;20>>50;50>>100;100");
      Collection<Point> points =
new CollectionInterpreter<Point>(
         
Point.class).interpret(p.getProperty("list.points"));
     
for (Point pp : points) {
       
System.out.println(pp.getX() + " : " + pp.getY());
     
}
    }
catch (NoApropriateInterpeterFoundException e) {
     
e.printStackTrace();
   
} catch (InterpretationException e) {
     
e.printStackTrace();
   
}
  }

}

There is no method to get the collection. To do that, we create a CollectionInterpreter and we interpret the encoded String property. The output, as expected, is:

0.0 : 0.0
50.0 : 20.0
50.0 : 50.0
100.0 : 100.0

▲ Top

A Really Complicated Example▲ Top

Joperties is using the registered interpreters to interpret composite classes. One example was shown earlier. The most complex composite type as of this writing is the RadialGradientPaint. If you include the use of Collections, the following code:

import java.awt.Color;
import java.awt.RadialGradientPaint;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.util.HashSet;
import java.util.Set;

import joperties.Joperties;
import joperties.exceptions.EncodingException;
import joperties.exceptions.NoApropriateInterpeterFoundException;
import joperties.interpreters.CollectionInterpreter;

/**
*
@author Savvas Dalkitsis
*/
public class Test {
 
public static void main(String[] args) {
   
try {
     
Joperties p = new Joperties();
      Set<RadialGradientPaint> set =
new HashSet<RadialGradientPaint>();
      set.add
(new RadialGradientPaint(200, 200, 50, 150, 180,
         
new float[] { 0, 0.2F, 0.8F, 1 },
         
new Color[] { Color.BLACK, Color.YELLOW, Color.RED,
              Color.GREEN
}, CycleMethod.REFLECT));
      set.add
(new RadialGradientPaint(50, 50, 50, 0, 0, new float[] { 0,
         
1 }, new Color[] { Color.BLACK, Color.WHITE },
          CycleMethod.REPEAT
));
      p.setJoperty
("radial.gradient", set,
         
new CollectionInterpreter<RadialGradientPaint>(
             
RadialGradientPaint.class));
      System.out.println
(p.getProperty("radial.gradient"));
   
} catch (NoApropriateInterpeterFoundException e) {
     
e.printStackTrace();
   
} catch (EncodingException e) {
     
e.printStackTrace();
   
}
  }

}

Produces this output:

50.0;50.0|50.0|0.0;0.0|0.0<<1.0|0x000000<<0xffffff|REPEAT>>200.0;200.0|50.0|150.0;180.0|0.0<<0.2<<0.8<<1.0|0x000000<<0xffff00<<0xff0000<<0x00ff00|REFLECT

As you can see, Joperties can produce very complicated Strings. You may also noticed that the RadialGradient contains some properties that are encoded as a Collection (the fractions and the colors in this case) but instead of being separated by ">>" they are separated by "<<". This was done so that you can create a Collection of RadialGradients. This also demonstrates a limitation of Joperties. You must be careful of what data you encode because if the data contains a String that is used to separate parameters, then an InterpretationException will be thrown.

▲ Top