Wizard API updated!
Tim Boudreau has released a new version of the Swing Wizard library (version 0.997) that fixes the WizardException bug reported in JavaWorld's recent Open Source Java Project profile. The article's examples have been reworked to test out the new, improved WizardException. Thanks, Tim, for this helpful fix!
Open Source Java Projects: The Wizard API

Newsletter sign-up

Sign up for our technology specific newsletters.

Enterprise Java
View all newsletters

Email Address:

Chart your way to custom graph components

Learn to build a graph framework and custom graph components

Our custom graph components require manual drawing, so we'll need to subclass Canvas, which is the standard component provided for direct graphics manipulation. The technique we're going to use will be to override the paint method of Canvas with the custom drawing that we need. We will use the Graphics object, which is automatically passed into the paint method of all components, to access colors and drawing methods.

We'll create two custom graphing components: a bar chart and a line graph. We'll start by building a general framework class for the two graphs, which share some base elements.

Building a generic graph framework

The line graph and bar chart we're going to build are similar enough that we can create a generic Graph class to perform some of the tedious layout work. Once that's done we can then extend the class for the particular kind of graph we need.

The first thing to do when you design custom graphics components is to put pen to paper and draw a picture of what you need. Because we are counting pixels, it is easy to get mixed up about the placement of the elements. Putting some thought into the naming and positioning of elements will help you to keep the code cleaner and easier to read later on.

The line graph and the bar chart use the same layout for the title and lines, so we'll begin by creating a generic graph containing these two features. The layout we're going to create is shown in the figure below.


Our generic graph layout

To create the generic Graph class, we'll subclass Canvas. The center region is where actual graph data will be displayed; we'll leave this to an extension of Graph to implement. We'll implement the other elements -- a title bar, a vertical line to the left, a horizontal line on the bottom, and values for the range -- in the base class. We could specify a font and hard-code the pixel measurements in, but the user would be unable to resize the graph. A better approach is to measure the elements against the current size of the component, so that resizing the application will result in a correct resizing of the graph.

Here's our plan: We'll take a String title, an int minimum value, and an int maximum value in the constructor. These give us all the information we need to lay out the framework. We'll keep four variables for use in subclasses -- the top, bottom, left, and right values for the borders of the graph drawing region. We'll use these variables to calculate positioning of graph items later. Let's begin with a quick look at the Graph class declaration.

import java.awt.*;
import java.util.*;
public class Graph extends Canvas {
   // variables needed
   public int top;
   public int bottom;
   public int left;
   public int right;
   int titleHeight;
   int labelWidth;
   FontMetrics fm;
   int padding = 4;
   String title;
   int min;
   int max;
   Vector items;


To calculate the correct placement of graph elements, we first need to calculate the regions in our generic graph layout that make up the framework. To improve the appearance of the component, we add a 4-pixel padding to the outer edges. We'll add the title centered at the top, taking into account the paddding area. To make sure that the graph is not drawn on top of the text, we need to subtract the height of the text from the title region. We need to do the same thing for the min and max value range labels. The width of this text is stored in the variable labelWidth. We need to keep a reference to the font metrics in order to do the measurements. The items vector is used to keep track of all the individual items that have been added to the Graph component. A class used to hold variables related to graph items is included (and explained) after the Graph class, which is shown next.

1 | 2 | 3 | 4 | 5 | 6 | 7 |  Next >
Resources
  • Previous Step by Step articles