The previous example utilizes an invisible Frame object created by the ChartEncoder class to encode chart into one of the
image formats supported. This approach must be used when running applications with JVMs that does not support the
java.awt.image.BufferedImage class.
The need for an invisible Frame object is associated with the fact that the Image object has no public constructor, and it
must be created with the method Frame.createImage(int width,int height), which returns an Image object with a valid dimension.
The BufferedImage class, found in JDK 1.2 and newer versions, has a constructor and there is no need to create the Frame
instance. After creating an instance of BufferedImage, a reference to its graphical context is passed to the Graph.paint(Graphics g)
method, which paints the entire chart on it. After that, the BufferedImage instance is passed to one of the available
image encoders, and the encoded image is then outputted using an OutputStream object.
The previous offscreen application was adapted to demonstrate the use of the BufferedImage class for generation of GIF,JPEG or PNG encoded
images. The ChartEncoder class is not used, and the JPEG encoder is explicitly invoked.
import javax.swing.*; import java.awt.*; import java.awt.event.*; import com.jinsight.jetchart.*; import java.io.*; import java.util.Locale; import java.awt.image.BufferedImage; public class Main { public static void main(String[] args) { // Creates the BufferedImage instance with the same dimension of the Graph object. BufferedImage image=new BufferedImage(500,400,BufferedImage.TYPE_INT_RGB); Graph graph=new Graph(new String[]{"l1","l2","l3","l4","l5"}); // Some JetChart classes place calls to the method Graph.getLocale(), which only returns // a valid Locale object if the Graph object has been laid out on a container, like a // Frame or JFrame object. If the Graph object has not a parent, an exception is then // raised when the Graph.paint(Graphics g) method is invoked to paint chart on the // BufferedImage graphical context, telling that Graph must have a parent in order // to determine its locale. If we set the Graph object locale as below, the exception // is not raised. graph.setLocale(Locale.getDefault()); // If a BufferedImage object is used to generate offscreen images, the method below // must always be set to true. graph.setBufferedImageEnabled(true,BufferedImage.TYPE_INT_ARGB) graph.setOffScreenGraphEnabled(true); graph.setSize(500,400); graph.setTitle(new String[]{"The JetChart Library","Generating GIF/JPEG/PNG images with the BufferedImage class"}); graph.set3DEnabled(true); graph.setHorizontalGraphEnabled(true); StackBarSerie sb1=new StackBarSerie(new double[]{100,70,80,90,50},"Stacked bar series 1"); sb1.setColor(Color.green); StackBarSerie sb2=new StackBarSerie(new double[]{-40,-60,70,-80,90},"Stacked bar series 2"); sb2.setColor(Color.orange); graph.addSerie(sb1); graph.addSerie(sb2); graph.getGraphSet(0).getGrid().setEnabled(true); // Paints chart on the BufferedImage graphical context. Graphics g=image.getGraphics(); graph.paint(g); FileOutputStream out=null; try { File f=new File("output.jpg"); out=new FileOutputStream(f); System.out.println("Image encoding started..."); // Creates a jpeg encoder, passing the BufferedImage object, setting // the image quality(%) and passing the FileOutputStream object. JpegEncoder jpg=new JpegEncoder(image,85,out); // Encodes image. jpg.encode(); // Enable the following lines to gif encode image. Disable the jpeg // encoder and change the file extension accordingly. // GifEncoder gif=new GifEncoder(image,out); // gif.encode(); // Enable the following lines to png encode image. Disable the jpeg // encoder and change the file extension accordingly. // The second parameter is the compression level, ranging from 1 to 9. // PngEncoder png=new PngEncoder(image,9,out); // png.encode(); System.out.println("Finished."); } catch (IOException e) { e.printStackTrace(); } finally { try { if (out!=null) out.close(); // A call to System.exit(0) has to be placed at this point to stop // application, because the AWT thread remains active. // There is no need for the line below if this application is run using // JDK 1.4 or newer versions. System.exit(0); } catch (IOException e) { } } } }