Saturday, November 27, 2010

Dynamic JSF 2.0 Page

I have had a number of folks ask about templates and JSF. There seems to be a misconception that you need a template for all of your content, and that the content can not be dynamically generated for a page. This is not true! I am not sure where this comes from, but it is not uncommon question.

Dynamic JSF Page

The example NetBeans project in the link below, demonstrates how to to use the binding attribute to inject the required information into a page before rendering it. I have added the binding attribute to the <body> tag. This allows me to modify the content of the page body before it is rendered.

I have also included how to use the ValueExpression to set the value of the rendered text. This example should be sufficient to demonstrate the capabilities.

The project code is a NetBeans project: DynamicJSF.zip

Thursday, November 25, 2010

Oracle Certified Java Programmer Boot Camp Code Examples

Java Mascot introducing Netbeans.Image via Wikipedia
I uploaded all of my code examples today for the free Oracle™ Certified Java™ Programmer Boot Camp that I do for the Greenville Java Users Group (GreenJUG).

You can find more information on the JUG site about the boot camp, and from the links below. The projects are NetBeans 6 files.

You need to still need to attend for the presentations! If I posted those, you wouldn't feel the need to come and participate.

Code Examples

Links



Enhanced by Zemanta

Wednesday, November 24, 2010

Creating Charts on Headless Systems: JFreechart and Rogue Wave

JFreechart Example
This week we had an interesting conundrum at work. We had a headless server which is not uncommon, that would not generate charts in our web based application. Apparently some of the charts are not used very often, or it would have been reported sooner. The charts in question were originally created using Rogue Wave Software charting software from 1999-2000. This software was used to create charts in AWT based applications. Yes, I said AWT not Swing, and I know that it is very old.

The particular charts do not have replacements available in free charting software like JFreechart currently, and are available only as commercial software. We had purchased the original software and licenses from Rogue Wave, and did not want to purchase new commercial software.

Now to the conundrum. Since Java 1.4, heavyweight AWT and Swing components throw a HeadlessException, if you attempt to run them on a headless system.

As you can see from the list, it does not leave much room for the developer to work with in a headless environment. Fair enough, AWT/Swing are GUI environments.

The graphical libraries used to create charts in the case of Rogue Wave and JFreechart generally expect a GUI framework. Rogue Wave is expecting to generate the chart images in a Window, or one of its subclasses like Frame. This can cause an issue as you can see. So I am left with a couple of components that I can use like Component, Canvas, and Panel.

You can create a headless environment and check it with the code below.

System.setProperty("java.awt.headless", "true");
boolean headless = GraphicsEnvironment.isHeadless();
System.out.println("Headless: " + headless);

So how do you generate the charts, or create images in general on a headless system. It turns out to be quite simple. Since all components have a paint(Graphics g) method, and JFreechart has a createBufferedImage() method. These turn out to be the keys.

Solution

We need to create a BufferedImage which we can pass to the Component to paint. Once we create the image to paint to, we simply ask the component to paint it, and use ImageIO to output our chart.

Note: You will need to have the Rogue Wave graphing and gif libraries, or you may comment out those code sections.

NetBeans 6.9 project files: HeadlessAWT.zip

Headless.java

/*
 *  Copyright 2010 Blue Lotus Software.
 *  Copyright 2010 John Yeary.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *  under the License.
 */
package com.bluelotussoftware.graph.headless.example;

import java.awt.*;
import java.io.*;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.util.Locale;
import com.roguewave.chart.awt.datamodels.v2_2.SampleData;
import com.roguewave.chart.awt.standard.v2_2.beans.PieChart;
import com.roguewave.chart.awt.standard.v2_2.beans.LineChart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.encoders.ImageFormat;
import org.jfree.data.general.DefaultKeyedValuesDataset;
import org.jfree.data.general.DefaultPieDataset;

/**
 *
 * @author John Yeary
 * @version 1.0
 */
public class Headless {

    private static BufferedImage generateRectangle(Component component, int width, int height) {
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = bufferedImage.getGraphics();
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, width, height);
        graphics.setColor(Color.ORANGE);
        graphics.fill3DRect(50, 50, 300, 300, true);
        component.paint(graphics);
        return bufferedImage;
    }

    private static BufferedImage generateRectangle(Component component) {
        return generateRectangle(component, 400, 400);
    }

    private static BufferedImage generateCylinder(int width, int height) {
        Panel panel = new Panel();
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics graphics = image.getGraphics();
        graphics.setColor(Color.WHITE);
        graphics.fillRect(0, 0, width, height);
        graphics.setColor(Color.ORANGE);
        graphics.drawOval(100, 100, 50, 75);
        graphics.fillOval(200, 100, 50, 75);
        graphics.drawLine(125, 100, 225, 100);
        graphics.drawLine(125, 175, 225, 175);
        panel.paint(graphics);
        return image;
    }

    private static boolean save(BufferedImage image, Component component) {
        boolean success = false;
        try {
            ImageIO.write(image, "gif", new FileOutputStream(component.getClass().getSimpleName() + ".gif"));
            success = true;
        } catch (FileNotFoundException fnfe) {
            fnfe.printStackTrace(System.err);
        } catch (IOException ex) {
            ex.printStackTrace(System.err);
        }
        return success;
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws IOException {
        System.setProperty("java.awt.headless", "true");
        boolean headless = GraphicsEnvironment.isHeadless();
        System.out.println("Headless: " + headless);
        Toolkit tk = Toolkit.getDefaultToolkit();
        tk.beep();

        BufferedImage bufferedImage = null;
        boolean success = false;

        // ---------------------------------------------------------------------------------------------- //
        Component component = new Component() {

            private static final long serialVersionUID = 3109256773218160485L;
        };
        Canvas canvas = new Canvas();
        Panel panel = new Panel();
        // ---------------------------------------------------------------------------------------------- //

        // Drawing Examples
        bufferedImage = Headless.generateRectangle(component);
        success = Headless.save(bufferedImage, component);
        System.out.println("Created " + component.getClass().getSimpleName() + " : " + success);
        success = false;

        bufferedImage = Headless.generateRectangle(canvas);
        success = Headless.save(bufferedImage, canvas);
        System.out.println("Created " + canvas.getClass().getSimpleName() + " : " + success);
        success = false;

//        bufferedImage = Headless.generateRectangle(panel);
//        success = Headless.save(bufferedImage, panel);
//        System.out.println("Created " + panel.getClass().getSimpleName() + " : " + success);
//        success = false;

        bufferedImage = Headless.generateCylinder(400, 400);
        success = Headless.save(bufferedImage, panel);
        System.out.println("Created " + panel.getClass().getSimpleName() + " : " + success);
        success = false;
        // ---------------------------------------------------------------------------------------------- //

        // Rogue Wave Examples
        SampleData sd = new SampleData();
        LineChart lineChart = new LineChart();
        lineChart.setData(sd);
        PieChart pieChart = new PieChart();
        pieChart.setData(sd);

        // The chart size is required.
        lineChart.setSize(400, 400);
        pieChart.setSize(400, 400);

        bufferedImage = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = (Graphics2D) bufferedImage.getGraphics();
        lineChart.paint(g);
        ImageIO.write(bufferedImage, ImageFormat.PNG, new FileOutputStream("LineChart.png"));
        pieChart.paint(g);
        ImageIO.write(bufferedImage, ImageFormat.PNG, new FileOutputStream("PieChart.png"));
        // ---------------------------------------------------------------------------------------------- //

        // JFreechart Examples
        DefaultPieDataset dpds = new DefaultKeyedValuesDataset();
        dpds.setValue("Java", 60.0);
        dpds.setValue("C++", 20.0);
        dpds.setValue("MS Technologies", 10.0);
        dpds.setValue("Misc.", 10.0);

        JFreeChart jfc = ChartFactory.createPieChart("Programming Languages", dpds, true, true, Locale.ENGLISH);
        bufferedImage = jfc.createBufferedImage(400, 400);
        ImageIO.write(bufferedImage, "gif", new FileOutputStream("jfc-piechart.gif"));
    }
}

Enhanced by Zemanta

Popular Posts