Using the BIRT charting API in a Java Swing application
The BIRT charting API does not rely on the BIRT design engine or the BIRT report engine, nor does it process a BIRT report design file. You can use the BIRT charting API to generate a chart in any Java application.
The program shown in Listing 6‑24 uses the BIRT charting API to build a chart in a Java Swing application.
Listing 6‑24 Java Swing charting application
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
 
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
 
import java.util.HashMap;
import java.util.Map;
 
import javax.swing.JFrame;
import javax.swing.JPanel;
 
import org.eclipse.birt.chart.api.ChartEngine;
 
import org.eclipse.birt.chart.device.IDeviceRenderer;
import org.eclipse.birt.chart.device.IUpdateNotifier;
 
import org.eclipse.birt.chart.exception.ChartException;
 
import org.eclipse.birt.chart.factory.GeneratedChartState;
import org.eclipse.birt.chart.factory.Generator;
 
import org.eclipse.birt.chart.model.Chart;
import org.eclipse.birt.chart.model.ChartWithAxes;
 
import org.eclipse.birt.chart.model.attribute.AxisType;
import org.eclipse.birt.chart.model.attribute.Bounds;
import org.eclipse.birt.chart.model.attribute.IntersectionType;
import org.eclipse.birt.chart.model.attribute.LegendItemType;
import org.eclipse.birt.chart.model.attribute.Position;
import org.eclipse.birt.chart.model.attribute.TickStyle;
 
import org.eclipse.birt.chart.model.attribute.impl.BoundsImpl;
import org.eclipse.birt.chart.model.attribute.impl
.ColorDefinitionImpl;
 
import org.eclipse.birt.chart.model.component.Axis;
import org.eclipse.birt.chart.model.component.Series;
 
import org.eclipse.birt.chart.model.component.impl.SeriesImpl;
 
import org.eclipse.birt.chart.model.data.NumberDataSet;
import org.eclipse.birt.chart.model.data.SeriesDefinition;
import org.eclipse.birt.chart.model.data.TextDataSet;
 
import org.eclipse.birt.chart.model.data.impl.NumberDataSetImpl;
import org.eclipse.birt.chart.model.data.impl
.SeriesDefinitionImpl;
import org.eclipse.birt.chart.model.data.impl.TextDataSetImpl;
 
import org.eclipse.birt.chart.model.impl.ChartWithAxesImpl;
 
import org.eclipse.birt.chart.model.layout.Legend;
import org.eclipse.birt.chart.model.layout.Plot;
 
import org.eclipse.birt.chart.model.type.BarSeries;
 
import org.eclipse.birt.chart.model.type.impl.BarSeriesImpl;
 
import org.eclipse.birt.core.framework.PlatformConfig;
 
/*
* The selector of charts in Swing JPanel.
*/
 
public final class SwingChartingApp extends JPanel implements
IUpdateNotifier,
ComponentListener
{
private static final long serialVersionUID = 1L;
private boolean bNeedsGeneration = true;
private GeneratedChartState gcs = null;
private Chart cm = null;
private IDeviceRenderer idr = null;
private Map contextMap;
 
/*
* Create the layout with a container for displaying a chart
*/
public static void main( String[ ] args )
{
SwingChartingApp scv = new SwingChartingApp( );
JFrame jf = new JFrame( );
jf.setDefaultCloseOperation( JFrame.DISPOSE_ON_CLOSE );
jf.addComponentListener( scv );
Container co = jf.getContentPane( );
co.setLayout( new BorderLayout( ) );
co.add( scv, BorderLayout.CENTER );
 
Dimension dScreen = Toolkit.getDefaultToolkit( )
.getScreenSize( );
Dimension dApp = new Dimension( 800, 600 );
jf.setSize( dApp );
jf.setLocation( ( dScreen.width - dApp.width ) / 2,
( dScreen.height - dApp.height ) / 2 );
jf.setTitle( scv.getClass( ).getName( ) + " [device="
+ scv.idr.getClass( ).getName( ) + "]" );//$NON-NLS-1$
jf.setVisible( true );
}
 
/*
* Connect with a SWING device to render the graphics.
*/
SwingChartingApp( )
{
contextMap = new HashMap( );
try
{
PlatformConfig config = new PlatformConfig( );
config.setProperty( "STANDALONE", "true" ); //$NON-NLS-1$
//$NON-NLS-2$
idr = ChartEngine.instance( config ).getRenderer(
"dv.SWING" );//$NON-NLS-1$
}
catch ( ChartException ex )
{
ex.printStackTrace( );
}
cm = createBarChart( );
}
/* Build a simple bar chart */
public static final Chart createBarChart( )
{
ChartWithAxes cwaBar = ChartWithAxesImpl.create( );
 
/* Plot */
cwaBar.getBlock( )
.setBackground( ColorDefinitionImpl.WHITE( ) );
cwaBar.getBlock( ).getOutline( ).setVisible( true );
Plot p = cwaBar.getPlot( );
p.getClientArea( ).setBackground(
ColorDefinitionImpl.create( 255, 255, 225 ) );
p.getOutline( ).setVisible( false );
 
/* Title */
cwaBar.getTitle( ).getLabel( ).getCaption( )
.setValue( "Bar Chart" );
 
/* Legend */
Legend lg = cwaBar.getLegend( );
lg.getText( ).getFont( ).setSize( 16 );
lg.setItemType( LegendItemType.CATEGORIES_LITERAL );
 
/* X-Axis */
Axis xAxisPrimary = cwaBar.getPrimaryBaseAxes( )[0];
xAxisPrimary.setType( AxisType.TEXT_LITERAL );
xAxisPrimary.getMajorGrid( )
.setTickStyle( TickStyle.BELOW_LITERAL );
xAxisPrimary.getOrigin( )
.setType( IntersectionType.VALUE_LITERAL );
xAxisPrimary.getTitle( ).setVisible( true );
 
/* Y-Axis */
Axis yAxisPrimary = cwaBar
.getPrimaryOrthogonalAxis( xAxisPrimary );
yAxisPrimary.getMajorGrid( )
.setTickStyle( TickStyle.LEFT_LITERAL );
yAxisPrimary.setType( AxisType.LINEAR_LITERAL );
yAxisPrimary.getLabel( ).getCaption( ).getFont( )
.setRotation( 90 );
 
/* Data Sets */
TextDataSet categoryValues = TextDataSetImpl
.create( new String[]{ "Item 1", "Item 2", "Item 3"} );
NumberDataSet orthoValues = NumberDataSetImpl
.create( new double[]{ 25, 35, 15 } );
 
/* X-Series */
Series seCategory = SeriesImpl.create( );
seCategory.setDataSet( categoryValues );
 
SeriesDefinition sdX = SeriesDefinitionImpl.create( );
sdX.getSeriesPalette( ).shift( 0 );
xAxisPrimary.getSeriesDefinitions( ).add( sdX );
sdX.getSeries( ).add( seCategory );
 
/* Y-Series */
BarSeries bs = (BarSeries) BarSeriesImpl.create( );
bs.setDataSet( orthoValues );
bs.setRiserOutline( null );
bs.getLabel( ).setVisible( true );
bs.setLabelPosition( Position.INSIDE_LITERAL );
 
SeriesDefinition sdY = SeriesDefinitionImpl.create( );
yAxisPrimary.getSeriesDefinitions( ).add( sdY );
sdY.getSeries( ).add( bs );
return cwaBar;
}
 
public void regenerateChart( )
{
bNeedsGeneration = true;
repaint( );
}
 
public void repaintChart( )
{
repaint( );
}
 
public Object peerInstance( )
{
return this;
}
public Chart getDesignTimeModel( )
{
return cm;
}
 
public Object getContext( Object key )
{
return contextMap.get( key );
}
 
public Object putContext( Object key, Object value )
{
return contextMap.put( key, value );
}
 
public Object removeContext( Object key )
{
return contextMap.remove( key );
}
 
public Chart getRunTimeModel( )
{
return gcs.getChartModel( );
}
 
public void paint( Graphics g )
{
super.paint( g );
Graphics2D g2d = (Graphics2D) g;
idr.setProperty( IDeviceRenderer.GRAPHICS_CONTEXT, g2d );
idr.setProperty( IDeviceRenderer.UPDATE_NOTIFIER, this );
Dimension d = getSize( );
Bounds bo = BoundsImpl.create( 0, 0, d.width, d.height );
bo.scale( 72d / idr.getDisplayServer( ).getDpiResolution());
Generator gr = Generator.instance( );
 
if ( bNeedsGeneration ) {
bNeedsGeneration = false;
try {
gcs = gr.build( idr.getDisplayServer( ),
cm,
bo,
null,
null,
null );
}
catch ( ChartException ex ) {
System.out.println( ex );
}
}
try {
gr.render( idr, gcs );
}
catch ( ChartException ex ) { System.out.println( ex ); }
}
 
public void componentHidden( ComponentEvent e ) { }
public void componentMoved( ComponentEvent e ) { }
public void componentResized( ComponentEvent e )
{
bNeedsGeneration = true;
}
public void componentShown( ComponentEvent e ) { }
 
}