[Home]   [Contents]   [Index]   [Javadoc] JCLASS
  [Frames]    [No Frames]
[Previous]   [Next]

JClass Component -
Circular Gauge

Features of JCCircularGauge * JCGauge and JCCircularGauge

Headers, Footers, and Legends * The Circular Scale Object

The Tick Object * The Range Object

The Needle Object * The Center Object

RadialConstraint and RadialLayout * Labels

Events and Listeners in JCGauge * Utility Functions for JCCircularGauge

Adding Other Components to a Gauge


Features of JCCircularGauge

JCCircularGauge is a subclass of JComponent whose on-screen representation looks like an analog circular measuring instrument. JCCircularGauge is a JavaBean.

 

JCCircularGauges are containers for interactive circular meters that use a needle to point to a value and allow it to be measured on a scale. Circular gauges are constructed using an assortment of objects that provide structured functionality to the component as a whole.

The major components in a circular gauge shows the components that may be used in a gauge. The central element is a circular scale, which resides in a JCGaugeArea. The only way that a scale indicates its presence is if its foreground color is different from that of the gauge. The visible objects are a center, and collections of needles, ticks and ranges. A center object, as its name implies, marks the center of a circular gauge. It may be a disk or an image. Needles perform measurement functions by pointing at scale values. Ticks provide visible scale markings with optional value labels so that scale values may be read. Ranges are bands that mark part or all of the scale to distinguish one part from another, like the red-line area of a tachometer. The range shown in The major components in a circular gauge runs along the circumference of the circular scale, thus marking its location. Outside the gauge area there is room for a header, footer, and legend. Header and footer elements are JComponents, typically JLabels, but the choice is yours. The legend is a JCLegend, a special type of JComponent that makes it easy to provide a legend that itemizes each component of a chosen type that the scale contains. Ranges are the default items for a legend, and may be itemized simply by calling gauge.getLegend().setVisible(true).

Alternatively, needles or other objects may be the items referred to in the legend list.

 

The major components in a circular gauge

Because the gauge and many of its constituents are subclassed from JComponent, you have considerable flexibility in designing its appearance. As well, it is easy to add additional items like numerical counters, images, and such to the gauge.

The gauge behaves like an analog device. If a more precise digital readout is desired, the needle's getValue() method, or the component's pick listener is employed to extract numeric values from the gauge. The odometer is a label positioned at the bottom of the speedometer shows a circular gauge functioning as a speedometer. The needle points to the car's current speed. A numeric counter has been added to function as an odometer, and another to display a digital readout of the speed. This reading is more precise than the indication of the speed given by the needle.

Interactions between mouse and needle may be turned on or off. When an interaction is enabled, an end user can control the placement of the needle. If you wish, interactions can be turned off and the component can be used simply as a display device.

 

The odometer is a label positioned at the bottom of the speedometer

You control the order in which objects are rendered to achieve your desired layering effect. See Rendering order for an explanation.

Caution: set a scale or a center, and add needles, ranges, and ticks to a gauge using the special set and add methods provided in JCGauge. Using standard java.awt.Container's add() methods does not take into account the gauge's special requirements. When using the special gauge add() methods you are still able to include an optional index that specifies the rendering order.

A gauge may have multiple instances of needles, ranges, and tick marks. In this case, the gauge maintains a collection for each of the object groups. The gauge has a needle list for keeping track of scale pointers, a range list for keeping track of the bands, called ranges, that can be used to mark various regions around the scale, and a tick list to keep track of the different tick objects.

Labels, which may be any JComponent, not just a JLabel, are created and manipulated individually rather than being stored in a list. There is a special-purpose method called addLabel(), for placing one at a specified location on the gauge.

Circular gauges may be added to other circular gauges. They may or may not share the same origin. See Adding Other Components to a Gauge for a discussion on how to place components on a gauge and for an example of placing a smaller circular gauge on top of a larger one.

A gauge's size is determined by the size of its container. The container's layout manager along with its preferred size setting determine the gauge's initial size. Gauges may be resized as long as the layout manager permits it.


JCGauge and JCCircularGauge

JCGauge and JCCircularGauge are the primary classes for a group of objects that as a whole combine to make a functioning circular gauge. JCGauge has methods for managing a header, footer, and legend, as well as methods for adding or removing needles, ranges, and ticks. Use these rather than the add() methods in JComponent.

The addLabel() methods in JCCircularGauge are there because these objects depend on a RadialConstraint class to position labels based on a specified angle and radial distance. (See the discussion in RadialConstraint and RadialLayout for more information.) Also, through its inner class GaugeType, it defines a set of configurations for circular gauges, such as LOWER_RIGHT_QUARTER_CIRCLE, or TOP_HALF_CIRCLE, allowing you to confine the gauge to a quadrant or a semicircle. There are nine choices in all. See the list of constants for GaugeType Properties later on in this section.

At any given time, each gauge contains one circular scale. A scale holds information about the minimum and maximum values for the scale, and the direction, clockwise or counterclockwise, in which scale values increase. The circular scale has start and stop angles that determine the portion of a full circle occupied by the scale. A needle object provides the visual indication of a particular value on the scale. Its own length is specified as a decimal fraction of the circular scale's radius. If the circular scale changes its size, the needle adjusts itself accordingly, maintaining a proper center position and proportional length relative to the size of the circular scale.


Constructors

JCGauge has an abstract no-argument constructor and JCCircularGauge has two. Of the two constructors for JCCircularGauge, one supplies its own scale, then populates it with a center (a disk or an image), a needle, and a set of tick marks. The other creates a gauge of the specified type. The scale, center, needles and ticks must be added separately.


Methods and Properties for JCGauge

Methods

JCGauge has these methods and properties:

JCGauge Method Description

addNeedle()

removeNeedle()

Adds or removes a needle to the needle collection for this gauge. Both take a needle as a parameter, and an optional second parameter, an index, specifying its position in the Vector of needles.

getNeedles()

Returns the list of needles associated with this scale.The list is a java.util.Vector.

addPickListener()

removePickListener()

Adds or removes a pick listener for this needle. See Events and Listeners in JCGauge.

addRange()

removeRange()

A gauge maintains a list of ranges associated with it. These methods add or remove a specified range from the collection. They take the range as a parameter and an optional second parameter, an index, for its position in the Vector of ranges.

addTick()

removeTick()

A gauge maintains a list of ticks associated with it. These methods add or remove a specified tick from the collection. They take the tick as a parameter and an optional second parameter, an index, for its position in the Vector of ticks.

mouseClicked()

Sends pick events to listeners.

pick()

Given a screen location in pixels, returns the closest scale value as a JCGaugePickEvent.

sendPickEvent()

Broadcasts the pick event to interested listeners.

Properties

JCGauge Property Description

getFooter()

setFooter()

Returns or sets the footer for this gauge, a JComponent.

getGaugeArea()

setGaugeArea()

Returns or sets the JCGaugeArea for this gauge, a JCGaugeArea. These methods, although declared public, are internal to JClass. There should be no need to obtain a reference to a JCGaugeArea.

getHeader()

setHeader()

Returns or sets the header for this gauge, a JComponent.

getLegend()

setLegend()

Returns or sets the legend for this gauge, a JCLegend.

getScale()

setScale()

Returns or sets the scale associated with this gauge, a JCCircularScale.

getTicks()

setTicks()

Returns or sets the list of ticks for this gauge. The list is a java.util.Vector.

Inner class JCCircularGauge.GaugeType has these constants and methods:

GaugeType Constant Angular Span of the Circle, Semicircle, or Quadrant

BOTTOM_HALF_CIRCLE

180-0 degrees. See Angles In a Circular Scale for a discussion of angular measurement in JCCircularGauge.

FULL_CIRCLE

0-360 degrees

LEFT_HALF_CIRCLE

90-180 degrees

LOWER_LEFT_QUARTER_CIRCLE

180-270 degrees

LOWER_RIGHT_QUARTER_CIRCLE

270-0 degrees

RIGHT_HALF_CIRCLE

270-90 degrees

TOP_HALF_CIRCLE

0-180 degrees

UPPER_LEFT_QUARTER_CIRCLE

90-180 degrees

UPPER_RIGHT_QUARTER_CIRCLE

0-90 degrees

getStartAngle()

Returns the start angle

getSweepAngle()

Returns the sweep angle


Methods for JCCircularGauge

JCCircularGauge subclasses from JComponent, making it a JComponent with special capabilities for laying out sub-components radially.

JCCircularGauge Method Description

addLabel()
removeLabel()

Adds or removes a label on the gauge. This is a general-purpose method, suitable for laying out any JComponent it is given.

getScale()
setScale()

Gets or sets the scale used by the gauge. A scale contains the measurement parameters associated with a circular gauge.

getClosestNeedle()

Returns the closest needle to the clicked/dragged point.

mouseClicked()

Sends pick events to listeners and moves the closest needle with a CLICK interaction enabled to the value indicated by the mouse click.

mouseDragged()

Called during mouse drag events in the gauge to move the needle closest to the mouse.


Properties

A JCCircularGauge has the same properties as a JComponent and these additional ones:

JCCircularGauge Property Description

getCenter()

setCenter()

Returns or sets the center for this gauge.

setClosestNeedle()

Returns the closest needle to the clicked/dragged point. Returns closest needle of type CLICK/DRAG/CLICK_DRAG, or if there are none of these, the closest needle of type NONE. This property is read-only.

getGaugeType()

setGaugeType()

Returns or sets the gauge type, one of the JCCircularGauge.GaugeType enums.

For a full listing of the properties, see the API for com.klg.jclass.swing.gauge.JCCircularGauge.


Headers, Footers, and Legends

JCCircularGauge allows an optional header and footer, both of which may be a JComponent. Methods setHeader() and setFooter() in JCGauge are used to pass a JComponent, typically a JLabel, that is used as the header or footer. By default, the header, footer, and legend do not show. To display a header, use:

	// gauge is a reference to a JCCircularGauge
	gauge.getHeader().setVisible(true);

A gauge's legend is an instance of JCLegend, an abstract class that requires a subclass to provide a specific layout. A gauge uses JCGridLegend and its delegate to DefaultLegendPopulatorRenderer to provide a default implementation of JCLegend that uses range names as the items in the legend. If you wish to itemize ranges in a legend, simply show the gauge's default legend and DefaultLegendPopulatorRenderer does the rest.

	// gauge is a reference to a JCCircularGauge
	gauge.getLegend().setVisible(true);

Ranges have default names like range0, range1, and so on. Give a range a name of your own choosing as follows:

	// range is a reference to a JCCircularRange
	range.setRangeName("Danger zone");

Custom Legends

If you need a legend that itemizes needles or ticks then you can subclass DefaultLegendPopulatorRenderer and override getLegendItems() to provide your chosen item list with instances of JCLegendItem. The method in DefaultLegendPopulatorRenderer called createLegendItem() is used both for items and for the legend's title, the difference being that a null Color specification (the constructor's last parameter) indicates a title. Note that getLegendItems() returns a list of items. See GaugeInteractionExample.java, which creates a legend that lists the needles used in the gauge.


JCLegend

Interfaces

There are two interfaces associated with JCLegend. JCLegendPopulator is an interface implemented by classes that wish to populate a legend with data, and JCLegendRenderer is an interface implemented by a class that wishes to help render the legend.

DefaultLegendPopulatorRenderer implements both interfaces and provides a built-in mechanism for itemizing range objects in a legend.

Methods in JCLegend

Method Description

getLegendPopulator()

setLegendPopulator()

Returns or sets the JCLegendPopulator instance used to populate this legend.

getLegendRenderer()

setLegendRenderer()

Returns or sets the legend renderer class that is used to help draw the legend.

getOrientation()

setOrientation()

Returns or sets the Orientation property that determines how the legend information is laid out. Possible values are JCLegend.HORIZONTAL or JCLegend.VERTICAL.


The Circular Scale Object

One circular scale object at a time may belong to a JCCircularGauge component. The Gauge keeps a reference to it in JCGauge.


Circular Scales

A JCCircularScale has settable minimum and maximum values, start angle, stop angle1, and direction.

 

A circular scale has an extent property whose purpose is to avoid scaling problems when you want to have objects extend past the circumference of the scale. Objects exterior to the circumference may not resize properly because the border remains a fixed number of pixels no matter how greatly the window is resized, therefore there is a chance that the exterior objects may be clipped. By setting a scale's extent to be less than 1.0 you can place objects outside the extent yet keep them on the interior of the circumference, thus avoiding clipping problems if the scale is magnified.


Notes on Circular Scale's Properties

The Circular Scale object's job is to hold the required numerical information for the construction of a Circular Gauge but not any visual information except for the scale's foreground color. Displaying the information is the responsibility of needles, tick marks, ranges, and so on. All of these are shown in A circular scale showing representative values for its properties, along with the circular scale's property values which place the scale within the component, set the size of the circle, set the numerical range values, determine the part of the circle that is to be displayed, and which values the scale represents.

 

A circular scale showing representative values for its properties

It is also possible to provide a foreground color such as the one shown in A circular scale showing representative values for its properties.


JCScale and JCCircularScale

The JCCircularScale object and its superclass JCScale form the basis for all the quantifiable elements of the gauge2. It holds the following information: the minimum and maximum values for the quantity being measured, the start and stop angles where measurements begin and end, and a pick() method for processing a scale value corresponding to the point at which a mouse click occurred.

Radius

JCCircularScale has a getRadius() method that returns the size of the circular scale. Initially, the size of the gauge may be set using JComponent's setPreferredSize() method.

Min, max

These JCScale properties specify the beginning and ending values for the scale. Note that multi-turn functionality (multiple turns required to move from min to max) is not supported.

Specifying the Direction of Travel

setDirection(JCScale.Direction direction) controls the direction in which the scale's values increase, clockwise or counterclockwise. The two field values are:

Since JCCircularScale extends JCScale, the direction property can also be set using JCCircularScale.Direction.COUNTERCLOCKWISE.


Angles In a Circular Scale

The Circular Scale adopts an angular measurement convention that defines due east as the zero degree line. Angles increase in a counterclockwise direction, so that 90° is due north, 180° is due west, and 270° is due south.

Diagram of a Circular Scale's reference plane. illustrates the way that angular measurement is done in the Circular Scale, showing the x axis, y axis, and location of the zero degree line.

Once the start and stop angles of a circular scale have been chosen along with the maximum and minimum numerical values to be associated with them, one additional parameter, direction, sets whether the start angle corresponds to the minimum value or the maximum value. A maximum value may be attached to the scale's start angle by setting the direction parameter to clockwise. In the default situation, the direction is counterclockwise and the scale's min value is attached to the scale's start angle.

The start angle is usually less than the stop angle but it is not a requirement. For example, if the start and stop angles are chosen as 90° and 270°, and the values being measured begin at 100 and end at 200, setting the direction to clockwise causes the value 200 to be located at 90°. The values decrease around the scale, ending at 270° where a value of 100 is located. Thus, while the coordinate system for angular measurement never changes, the direction in which the scale's value parameter increases can be reversed.

 

Diagram of a Circular Scale's reference plane.

Start and stop angles

These two angles, defined in JCCircularGauge, specify the compass positions marking where the min and max values are located. A circular scale positions zero degrees at due east. Angles increase in the counterclockwise direction. A start angle may be greater than a stop angle, which would be the case if a scale's min value begins at the twelve o'clock position and its max value is at the three o'clock position. In this case, the start angle is ninety degrees and the stop angle is zero degrees.

These angles may be set in JCCircularScale's constructor. Alternatively, start and stop angles may be set using setStartAngle() and setStopAngle(), for instance:

	JCCircularScale scale = new JCCircularScale();
	scale.setStartAngle(15);

sets the scale's start angle at 15°.

 

A case where the start angle is greater than the stop angle

Rendering order

A render list, which in Java is often called the z-order of the components, is effectively created by the order in which components are added at execution time. This list determines in what order child objects are to be drawn. Components added last are drawn first. For example, by adding a needle and then a center, the center object is drawn first, then a needle, so that the needle is fully visible from center to tip instead of being partially covered by the center object. There are ways of manipulating the list so that a different drawing order can be specified. By drawing a needle first, it can appear to be attached to the edge of the center object rather than beginning at the center of the circle.

Assigning a color

A scale's color may be assigned in a JCCircularScale's constructor, or you may use JComponent's setForeground() method. By default, only the portion of the scale between its start and stop angles is colored. Any remaining portion retains the color of the gauge. If you wish to assign the color to the full scale, set the scale's paintCompleteBackground property to true:

	gauge.getScale().setPaintCompleteBackground(true);

 

Using paintCompleteBackground to determine how much of the scale is colored


Switches

A Switch is the software equivalent to its electrical counterpart, a device that has a set of discrete selectable positions. A simple switch may have only two states, on and off, or it may possess a number of selectable states. A Switch with six discrete states shows a Switch shaped like a pointer that has six discrete states.

Switches may be implemented by having your code control the way that the gauge reacts to user input. The easiest way to implement a switch is to choose a scale with integer values that correspond to switch positions and then set the gauge's snapToValue() to true:

	// make it discreet
    gauge.setSnapToValue(true);

See GaugeSwitchExample.java in the examples/elements directory for an example of a switch with six positions.

 

A Switch with six discrete states

If your requirement is for a switch with irregularly spaced stops you will need to add a pick listener and place the needle yourself in response to an end user's actions.


The Tick Object

Tick objects provide annotation marks on the circular scale. They provide the usual graduations that are often found on measuring devices. It's possible to have as many different tick objects as you want associated with a scale, for instance, major and minor graduations are realized using two tick objects. Typically, major tick marks have associated labels displaying numerical values, or you may supply your own definition for tick labels using the JCLabelGenerator interface. A property called drawTicks controls whether tick labels are drawn, and another called drawLabels controls whether the associated labels are drawn. Examples are given later in this section.

 

You can set the start value, stop value, the tick increment value, and the inner and outer extents for the tick marks. These extent parameters control the length of the tick line in the radial direction. They are specified as decimal fraction of the scale's radius. If you wish, you may specify a color and a width for the Tick object. If you do not set some property, the object chooses a default value. Both tick marks and tick labels may be turned on and off for each tick object.

You can set the precision for values displayed on tick mark labels, but be aware that reducing the precision may introduce rounding errors that may make the scale markings inaccurate. See "A note on precision" for an explanation.

 

Some Tick objects and their associated labels

You specify where the tick marks are to begin and where they are to end. This allows you to place tick marks over a sub-portion of the scale as is shown in the bottom left scale in Some Tick objects and their associated labels. Note the different tick styles in the figure. There is a custom tick style set for the scale in the lower right.

You can control the visibility of tick marks and their labels independently. Thus, you may choose to have only the labels showing if you wish.


Notes on the Tick Object

Associating a Tick object with a Scale

Tick objects need to know the scale for which they are to provide graduations. One of the parameters in the Tick object's constructor is the scale associated with the Tick object. Thus, a Tick object cannot be instantiated without specifying its associated scale.

Setting the tick type

There are six built-in types: circle, diamond, line, rectangle, reverse triangle, and triangle. The types are held in the JCTickStyle class. Example:

	JCTick tick = new JCCircularTick(...);
	tick.setTickStyle(JCTickStyle.TRIANGLE);

Defining your own tick style

You can define your own tick style by defining its shape using two arrays, one for the x coordinates and one for the y coordinates. Pass these arrays and an int specifying the number of points to JCTickStyle's constructor. Alternatively you could subclass JCTickStyle and define your new styles as constants. In either case, define a shape as an array of x and y coordinate points as you would for any Rectangle:

import com.klg.jclass.swing.gauge.JCTickStyle;
public class MyTickStyle extends JCTickStyle {
	public static final JCTickStyle NOTCHED_RECTANGLE = new JCTickStyle(
		new int[] {-10, -2, 0,  2,  10,  10,  2,  0, -2, -10},
		new int[] { 3,   3, 1,  3,   3,  -3, -3, -1, -2,  -2},
		10);
}

Use your newly-defined tick style by calling

	tick.setTickStyle(MyTickStyle.NOTCHED_RECTANGLE);

Setting the Tick object's placement

Tick marks are normally required at constant increments along a scale. The Tick object accomplishes this objective by using the associated scale's min and max values to determine appropriate values for the Tick object's start, stop, and increment values. Alternatively, you can control the spacing by setting automatic to False. You still control where the tick marks are to begin with startValue and where they are to end with stopValue, but you set how many tick marks there are with incrementValue.

Setting a Tick object's dimensions

The size of a tick mark is controlled with innerExtent and outerExtent. The values for both of these properties are numbers representing a proportion relative to the size of the associated circular scale. For instance, if the value set on innerExtent is 1.0, tick marks begin right at the circumference of the scale. They are drawn radially outward to the value set in outerExtent, which is also given as a ratio based on the radius of the associated circular scale.

Note: If your tick marks extend outside the scale, that is, at distances greater than the scale's radius and you allow the scale to be resized, you may have to increase the dimensions of the scale's borders to ensure that there is enough space to hold the tick marks, otherwise their outer extents may be clipped. Alternatively, set the circular scale's extent property to a value less than 1.0 and the tick's outer extent to 1.0 to give the appearance of tick marks lying outside the scale. In fact, they are within the scale's circumference, but they appear to lie outside the colored portion of the scale. See GaugeOutsideExample.java in the examples directory for an illustration of this technique.

If the inner extent is equal to the outer extent, then no ticks are drawn. The preferred way of hiding tick marks is to set drawTicks to false.

The width in pixels of the tick marks is specified in the tickWidth property. This property must be set for any tick style other than JCTickStyle.LINE.

Labeling tick increments

Labeling may be on or off, depending on the value of drawLabels. In automatic mode, one of the ways the object manages the span between labeled tick marks is by using the precision property's value. If you are controlling the placement of labeled tick marks (tick.setAutomatic(false)), make sure you have set precision properly, as explained in the following section, "A note on precision".

Place labels using labelExtent. An extent of 1.5 means that the label is placed outside the scale at a distance of one and one-half times the scale's radius, although if you permit the gauge to be resized the recommended approach is to choose a labelExtent of one or less and use the scale's extent property to make it appear to be outside the scale. This technique is employed in GaugeOutsideExample.java.

Custom tick labels

Tick labels are drawn with the help of the JCLabelGenerator interface. It contains a single method, makeLabel(), which takes three parameters: a JCTick, a scale value, and a radial constraint. Use the method in JCCircularTick called setLabelGenerator() to tell the gauge to use your custom labeling mechanism.

The following code snippet uses an anonymous inner class to add an implementation of JCLabelGenerator to a Tick object. The makeLabel() method is passed a reference to the Tick object in question, the scale value for the tick mark in question, and a reference to the tick's RadialConstraint. Only the value parameter is used in the following example. Since the tick marks are supposed to display temperature values, the custom labels are coded to produce temperature values along with their units of measurement, for example, 20° C.

	// create a label generator to mark 
	// the temperature values with their units
	    tick.setLabelGenerator(new JCLabelGenerator() {
	    	public JComponent makeLabel(JCTick tick, double value,
	    									RadialConstraint constraint) {
	    		String s = (value != 0) ? String.valueOf((int)value) 
									: "zero";
	 		JLabel label = new JLabel(s + "\u00B0 C");
	 		label.setToolTipText(s + "\u00B0 C");
	    		return label;
	    	}
    });

The code adds "° C" to each value except 0°, where it supplies the word "zero" instead.

For an example of a custom label in a user-defined class, see GaugeSwitchExample.java.

Another reason for using custom tick labels is to provide an offset between a label and its associated tick mark. Normally a label lines up with its tick mark so that a line joining the center of the scale and a tick mark also goes through the center of the tick mark's label. You can use JCLabelGenerator to offset the label, since a RadialConstraint is passed as one of the parameters of makeLabel().

A note on precision

If precisionUseDefault() is false, the value specified in setPrecision() is used as well, otherwise a default value for precision is determined. The precision setting affects the width of the label and therefore the number of labels that may be used without overlapping. The effect is quite noticeable if automatic is true. The number of labels changes as the scale is zoomed, becoming fewer during contraction so that the label on one number does not overlap adjacent labels, or becoming more numerous during expansion so that labeled marks do not become too widely separated. Wider labels will be fewer in number compared to the same scale with shorter tick labels. All this happens because the Tick object automatically calculates the number of tick labels. Note that drawLabels must be true or the labels won't show.

The value of the precision property controls how tick labels are interpreted. There are three cases to consider:

Failure to set the precision property may be the source of a misleading scale. As an example, setting the start value of a Tick object at -25, the stop value at 160, and allowing the default precision sets the precision to -1. In this case the value -25 is rounded to -20, resulting in a misleading scale. Setting the precision to 0 rectifies the problem because this specifies that digits in the units column must not be rounded.


Properties

The tick object has the following get/set methods:

JCTick Method Description

getAutomatic()

setAutomatic()

Controls whether the tick object is functioning in automatic mode or in manual mode. If it is in automatic mode, the associated scale's min and max values and the value of precision are used to determine "pleasing" tick start, stop, and increment values. Tick spacing is calculated by the gauge and any settings to these properties will be ignored, that is, the values reset to the automatic values. If the tick object is in manual mode, the values in startValue, stopValue, and incrementValue can be set by the user.

getDrawLabels()

setDrawLabels()

Returns the boolean controlling the drawing of labels. If true, use the value of precision to place a numeric label on each tick value.

getDrawTicks()

setDrawTicks()

Returns the boolean controlling the drawing of tick marks. If true, use the value of precision or incrementValue to determine how many tick marks to draw.

 

getFont()

Returns the Font used for tick mark labels. (java.awt.Component)

getFontColor()

setFontColor()

Returns or sets the Color used for tick mark labels.

getIncrementValue()

setIncrementValue()

The tick increment value. In automatic mode, this value is read-only. In non-automatic mode, this value can be changed.

getInnerExtent()

setInnerExtent()

The inner (towards the center of a circular scale) extent of each tick drawn. This value is related to the radius of an associated circular scale. A value of 0.9 means each tick's inner extent is 0.9 times the radius value of the scale away from the origin.

getLabelExtent()

setLabelExtent()

The location of the center of each label. This value is related to the radius of the associated circular scale. A value of 1.1 means each label's extent is 1.1 times the radius value of the scale away from the origin. Note: be aware that extending the label outside the scale may require adjustment of the borders. For labelExtents greater than one, consider setting the gauge's extent property to some number less than one and setting the tick's labelExtent to one. This achieves the same effect and eliminates the risk of clipping the labels.

getLabelGenerator()

setLabelGenerator()

Returns the label generator associated with this tick. Consult the API for interface JCLabelGenerator and its makeLabel() method for information on defining your own labels. A minimal example is given in the section on Labeling tick increments in this chapter.

getOuterExtent()

setOuterExtent()

The outer extent of each tick drawn. Outer extent values increase towards the component's boundary. This value is related to the radius of the associated circular scale. A value of 1.1 means each tick's outer extent is 1.1 times the radius value of the scale in a direction away from the center. Note: extending the tick mark outside the scale may require adjustment of the borders. For tick extents greater than one, consider setting the gauge's extent property to some number less than one and setting the tick's outerExtent to one. This achieves the same effect and eliminates the risk of clipping the tick marks.

getPrecision()

setPrecision()

Returns the format of the tick label. This property defines the number of digits of precision after the decimal point to be used for labels. If its value is zero or less, the labels will all be integers.

Positive values denote the number of places after the decimal point (for example, 3 means multiples of 0.001); negative values indicate the positive number of zeros to be used before the decimal place (for example, -3 means numbering will be in multiples of 1000).

A side effect of setting this property is to set the corresponding precisionUseDefault property to false.

Failure to set the precision property may be the source of a misleading scale. As an example, setting the start value of a Tick object at -25, the stop value at 160, and allowing the default precision sets the precision to -1. In this case the value -25 is rounded to -20, resulting in a misleading scale. Setting the precision to 0 rectifies the problem because this specifies that digits in the units column must not be rounded.

getPrecision-UseDefault()

setPrecision-UseDefault()

If true, use gauge-determined precision for tick labels, otherwise use startValue, stopValue and incrementValue to place ticks along the scale. If you set this property to false you should set a value for precision as well.

getScale()

setScale()

Returns the scale associated with this tick. Tick marks must be associated with a scale so this is enforced by the Tick object's constructor.

getStartValue()

setStartValue()

In non-automatic mode use this value as the start value. The value must be between the associated scale's min and max values, including end points.

getStopValue()

setStopValue()

In non-automatic mode use this value as the stop value. The value must be between the associated scale's min and max values, including end points.

getTickColor()

setTickColor()

The Color of the tick mark.

getTickStyle()

setTickStyle()

Predefined tick styles are JCTickStyle.CIRCLE, JCTickStyle.DIAMOND, JCTickStyle.LINE, JCTickStyle.RECTANGLE, JCTickStyle.REVERSE_TRIANGLE, andJCTickStyle.TRIANGLE. Extend JCTickStyle to define your own shape for tick marks, or define one by passing x and y coordinate points to JCTickStyle's constructor.

getTickWidth()

setTickWidth()

The width in pixels of the widest part of the object. Ticks whose style is circle or line ignore this property.


Sample Code

The following example illustrates using the Tick object's constructor. If you create a gauge using one of the convenience constructors you already have a tick object associated with the scale that you can access using code like

	JCCircularTick tick = (JCCircularTick) 
							gauge.getScale().getTicks().elementAt(0);

and then simply set the properties you wish to change from their default values. Nonetheless, it is often useful to create Tick objects from scratch and set properties in the constructor. This way you inspect each property and determine its appropriateness for your application. Here's an example:

	// create a Tick object and set its properties
	JCTick tick = new JCCircularTick(
    		scale, 		// the associated circular scale
		false, 		// automatic tick generation
		0, 		// start
		300, 		// stop
		25, 		// increment
		false,		// precisionUseDefault
		0,		// precision
		2,		// width
		true,		// draw labels
		true,		// draw ticks
		0.75,		// label extent
		0.85,		// inner extent
		1.0,		// outer extent
		Color.white,
		JCTickStyle.LINE,
		new Font("Helvetica", Font.BOLD, 18),
		Color.white);

 


The Range Object

On circular scales, ranges are rings or partial rings used to emphasize certain sections of the scale by coloring them. By using Range objects, an implementor can draw arcs (which may be full circles) and provide differently colored subdivisions on the scale.

If the range is narrow enough it has the appearance of a tick mark. This effect may be of use if you wish to provide special tick marks, such as those marking the dynamically changing maximum and minimum values on a temperature scale. See the demo TemperatureFluctuationExample.java.

 

Ranges are associated with a scale. There may be multiple ranges for the same scale.

You can control the inner and outer radii (and thus the thickness) of the range. As well, you set start-stop values (and thus the breadth), and the color. Two Range objects for a Circular Scale object shows two range objects on a circular scale. The thinner one spans the entire scale and appears as the circumference of the scale. The thicker one spans the region between tick marks 20 and 80. The diagram shows how a start value, stop value, inner extent, and outer extent determine the shape of a range.

 

Two Range objects for a Circular Scale object

A range object that is the same size as its associated scale shows a Circular Gauge component in which one Range object covers another, partially obscuring it. The drawing order in A range object that is the same size as its associated scale is first the semicircular range, followed in succession by the 20-80 range, the tick marks, the needle, and finally the center. If the objective is to show the semicircular range, draw the 20-80 range first. This topic is discussed in more detail in the next section.

 

A range object that is the same size as its associated scale


Notes on the Range Object's Properties

Coloring a Range

A Range object's color is set by the first parameter in its constructor. Use the setForeground() method to change the color of a range once it has been instantiated.

Associating a Range with a Circular Scale

A Range object has to be associated with a parent scale by providing a reference to a JCCircularScale in the constructor, or by using the setScale() method once a range has been instantiated.

A range spans a region of its associated scale, but to be visible it must have a thickness as well as a span. Properties innerExtent and outerExtent control the inner and outer limits of its thickness. Values for these properties are given as ratios based on the size of its associated scale. For example, an inner extent of 0.75 and an outer extent of 1.25 mean that the thickness is half the radius of an associated circular scale and is placed symmetrically over the circumference

Drawing Ranges in Java 1.1

If you are using Java 1.1, one Range object may not form the background for another Range object3. Use three Range objects to achieve the effect of one range on top of another. Layering ranges on a scale shows three Range objects on a circular scale. Two gray ranges, one inside the circumference of the scale and the other outside, combine to give the appearance of a single gray range in the background of a black semicircular range. The range that goes from 0 to 100 has an inner radius of 0.95 and an outer radius of 1.0, therefore it lies along the circumference of the circular scale. The inner gray range has an inner extent of 0.75 and an outer extent of 0.95, while the outer gray range has an inner extent of 1.00 and an outer extent of 1.25.

 

Layering ranges on a scale

Objects are drawn in reverse order, so they are added as follows:

	gauge.addTick(tick); // gauge is an instance of JCCircularGauge
	gauge.addRange(innerBand);
	gauge.addRange(circumfrence);
	gauge.addRange(outerBand);
	gauge.setCenter(center)

The outer band is drawn first, then the circumference, then the inner band, and finally the tick marks.

Use the setVisible() method of a range to control when the range is visible as the application runs, and isShowing() to test its visibility.

Extending past the scale

If you wish to use an offset to shift a range beyond the end of the tick marks, create a circular scale spanning all the values you need to display but supply tick marks for one portion of the scale and a range for another portion.

 

An offset is applied to the outer range of Two Range objects for a Circular Scale object

As shown in An offset is applied to the outer range of Figure 9, an offset appears to begin before the start of the scale. The scale's settings are max = 120, min = -20, startAngle = -36°, stopAngle = 216°. These were calculated to be consistent with the offset given to the range, and to maintain a semicircular appearance for the labeled part of the scale.


Constructor for JCCircularRange

The sole constructor is:

	JCCircularRange(java.awt.Color								foreground, 
					JCCircularScale scale,
					double 				innerExtent, 
					double 				outerExtent, 
					double 				startValue, 
					double 				stopValue)

All range properties are set in the constructor along with associating a range with a circular scale. Range properties are listed next.


Methods and Properties for JCRange and JCCircularRange

JCRange Method Description

getInnerExtent()

setInnerExtent()

Returns or sets the ratio of the radius' length at which to start drawing this range from the center outwards. For example, a value of 0.5 means the inner extent should begin one-half the distance between the scale's origin and the scale's circumference.

getOuterExtent()

setOuterExtent()

Returns or sets the value at which the outer boundary of the range is drawn. The value is expressed as a ratio of the radius' length. For example, a value of 1.5 means the outer extent lies 1.5 times the scale's radius away from the center.

getScale()

setScale()

Returns or sets the scale associated with this range.

getStartValue()

setStartValue()

Returns or sets the scale value (not the angle) where the range is to begin. This should be between the associated scale's min and max values.

getStopValue()

setStopValue()

Returns or sets the scale value (not the angle) where the range ends. This should be between the associated scale's min and max values.

 

Additional Methods Description

setForeground()

Method inherited from class javax.swing.JComponent. Used to dynamically color the range after it has been instantiated.

setVisible()

Method inherited from class javax.swing.JComponent. Used to dynamically show or hide a range.

 

JCCircularRange Property Description

innerArcStartCompensator

Compensates for awt drawArc precision problems when drawing the inner arc of the range. For JDK 1.1 only. Use if a spurious line joins the center of the scale to the inner extent of a range. Its parameter is the adjustment angle in degrees needed to cure the problem.

innerArcStopCompensator

Compensates for awt drawArc precision problems when drawing the inner arc of the range. For JDK 1.1 only. Use if a spurious line joins the center of the scale to the inner extent of a range. Its parameter is the adjustment angle in degrees needed to cure the problem.


Sample Code

Set the property values for the Range object in its constructor using the sample below as a guide.

// create a range that marks the circumference of the scale
	circumference = new JCCircularRange(
				Color.black,					// range color
				gauge.getScale(),					// one way of referencing a scale
				0.95,					// range inner extent
				1.00,					// outer extent is at the radius
				0,					// start value for the range
				100);					// stop value for the range


The Needle Object

Needle objects are the visible pointers on a Circular Scale object in a JCCircularGauge component. The Circular Gauge component allows more than one needle to be displayed on the same circular scale. Each needle has its own value and this value determines where on the scale it is positioned. The gauge manages its list of needles by keeping them in a Vector.

 

You can control the needle's color, length, width, and shape. The shape scales itself by using its length and width parameters.

The needle is drawn using its shape attribute. Basic constants exist for drawing triangles, pointers, and arrows, or you may provide your own shape.

The position of a needle, and therefore its associated value on a scale may be controlled programmatically, or via an end user action. A needle can be positioned by either clicking or dragging on the scale so long as a needle interaction is enabled. You can add a ChangeListener to a needle to respond to mouse actions. Additionally, the gauge has a JCGaugePickListener interface that facilitates getting the scale value corresponding to the spot where a mouse click occurs. You can enable click and drag interactions with a needle via the inner class called JCNeedle.InteractionType, which contains constants that specify the possible types of interactions between mouse actions and needles.

 

These are:

Interaction Type

Description

CLICK

The needle snaps to a mouse click.

CLICK_DRAG

The needle snaps to the mouse click, or follows a mouse drag.

DRAG

The needle snaps to the position of the mouse when the drag operation begins, then follows it until the mouse button is released.

NONE

Default case: neither clicking nor dragging affects the needle.

When a needle's value changes, a value changed callback is called to allow the program to disable or limit the change. Use sendEvents() to control whether an event is generated as a result of an action taken in the callback.


Notes on the Needle's Properties

Needle shapes

A needle has five possible built-shapes: arrow, tailed arrow, pointer, tailed pointer, or triangle, as shown in The five built-in needle shapes. The needle's length is set using the length property and is based on the associated circular scale. A needle begins at the center of the circular scale and extends outwards. For example, if its length property is set to 1.0, the needle's tip lies on the circumference of the associated circular scale. A needle's width is set using the needleWidth property.

 

The five built-in needle shapes

Defining a custom Needle style

It is possible to provide your own needle style if you require a custom shape. The method is the same as in Defining your own tick style. Extend JCNeedleStyle and define a shape as arrays of coordinate points using the same format as you would for java.awt.Rectangle. If you wish to keep your new needle styles as class constants, here is an example:

	import com.klg.jclass.swing.gauge.JCNeedleStyle;
 
	public class MyNeedleStyle extends JCNeedleStyle {
	/**
	 * A needle in the form of a rectangle using these points,
	 */
 
		public static final JCNeedleStyle RECTANGLE = new JCNeedleStyle(
	        new int[] { 50,	50,	200,	200},
	        new int[] { -5, 5,	  5,		- 5},
        			4);

Normally needles start at the center of the scale. Since the RECTANGLE defined above starts at 50, it does not start at the scale's center when it is drawn. Instead, this RECTANGLE starts some distance out from the center. You'll need to test your design to see that it scales properly if you begin your needle away from the center and you intend to allow scaling.

Coloring a Needle object

A needle's color is set in its constructor or by using javax.swing.JComponent.setForeground().

Controlling a Needle's visibility

You can show or hide a needle by setting its java.awt.Component.setVisible() method to true or false respectively. Test the visibility with java.awt.Component.isShowing().

Positioning a Needle with the mouse

Use the JCNeedle.InteractionType constants to determine how the needle responds to mouse clicks within the Circular Gauge component. To stop the needle from responding to the mouse use InteractionType.NONE. Other possible values are CLICK, DRAG, or CLICK_DRAG.


Constructors

JCNeedle has two constructors. The following one allows you to set properties, specify an interaction type, and associate it with its parent gauge:

	JCNeedle(java.awt.Color, 								foreground
		double,							needleWidth
		JCCircularGauge,							gauge 
		JCNeedle.InteractionType	,						interactionType
		boolean, 							visible 
		double, 							length 
		JCNeedleStyle, 							needleStyle 
		double, 							value
		)

There is also a constructor that requires a mention of the parent gauge. The rest of the needle's properties are set to default values. Its signature is:

	JCNeedle(JCCircularGauge gauge)


Methods and Properties

Needle properties allow you to control most aspects of the needle's appearance save for its drawing order (z order) with respect to the other gauge components. By managing the order in which gauge.addNeedle() is called relative to the other gauge.addComponent methods you achieve your intended layering effect. For instance, by adding a center and then a needle, the part of the needle under the center is obscured.

Needle Methods Description

addChangeListener()

removeChangeListener()

Adds or removes a listener interested in needle movements.

Needle Properties Description

getForeground()

setForeground()

Returns or sets the needle's color, a java.awt.Color.

getGauge()

setGauge()

Returns or sets the circular gauge associated with the needle.

getInteractionType()

setInteractionType()

The type of allowed mouse interaction. Possible values are:

JCNeedle.InteractionType.NONE

JCNeedle.InteractionType.CLICK

JCNeedle.InteractionType.DRAG

JCNeedle.InteractionType.CLICK_DRAG

getLength()

setLength()

Returns or sets the needle's length, expressed as a decimal fraction based on the circular scale's radius.

getNeedleStyle()

setNeedleStyle()

Returns or sets the shape of the needle. Possible values are:

JCNeedleStyle.ARROW

JCNeedleStyle.POINTER

JCNeedleStyle.TAILED_ARROW

JCNeedleStyle.TAILED_POINTER

JCNeedleStyle.TRIANGLE

 

It is possible to define your own needle style by extending JCNeedleStyle.

getNeedleWidth()

setNeedleWidth()

Returns or sets the width of the needle in pixels.

getPreferredSize()

Overridden so that the needle scales with the gauge.

getSendEvents()

setSendEvents()

Returns or sets a sendEvents flag; true means events will be sent when the needle's value changes, false means don't send the events. Use this method if your code might otherwise trigger a non-terminating sequence of events, such as setting a needle to its value plus one.

getValue()

setValue()

Returns or sets the scale value (not the scale angle) to which the needle points. When setting this value care should be taken to ensure it is between the scale's min and max values. A needle may not be dragged outside the scale's range, that is, before its startValue or after its stopValue.


Code Sample

If you have used the default gauge constructor, a needle is supplied. You can obtain a handle to it as follows:

	JCNeedle needle = ((JCNeedle)gauge.getNeedles().firstElement());

You can completely configure a needle at the time it is created. The following code sample shows how:

	needleOne = new JCNeedle(
				Color.red,						// needle's color
				10, 							// needle width
				gauge, 							// associated circular gauge
				JCNeedle.InteractionType.CLICK,						// interactionType
				true,							// visible?
				0.75,							// needle's proportional length
				JCNeedleStyle.POINTER,						// needle style
				25								// position on the scale
				);

The remaining step is to add the needle to the gauge:

	gauge.addNeedle(needleOne, 0); // Ensure the needle is on top.

Adding a change listener for needle movements

If you wish to take some action when a needle is moved you can use the fact that a needle movement generates a change event. You may add a change listener to the needle, for example:

	needleOne.addChangeListener(this); // For needle movements

The class (referenced by the this pointer in our example here) that is to respond to needle movements defines a stateChanged(ChangeEvent e) method to handle whatever action needs to be taken.


The Center Object

Center Object

A center object is associated with a gauge. You can set the center's radius and its color, then add it using the gauge's setCenter() method. Alternatively, you can specify an image for the center object.

 

A Center object is used to mark the position of the center of a circular scale in a JCCircularGauge component. It can be a colored circle or a user-supplied image. If an image is specified, the circular disk will not be drawn.

A center object must be associated with a circular gauge. Each of its three constructors demands a gauge as one of its parameters.

 

An image used as a center object


Notes on the Center Object

Setting the Center's color

Set the color of the Center object using the setForeground() method, or in the Center object's constructor. The result is a circular disk of this color at the center of the scale. The size of the disk is controlled by the center's radius property.

Associating a Center with a Gauge

Each Circular Gauge may have zero or one center objects. Specify the gauge using the gauge parameter in the Center object's constructor. The Center object may be replaced with an image if desired. The image does not rotate with the needle.

Sizing the disk

Set the size of the disk using the radius property. The value you pass it is a fraction based on the size of the radius of its associated circular scale. For instance, if you set a value of 0.2, the circular disk marking the center has a radius 20% as long as the radius of the circular scale.

Using an image as the visual

If you require anything other than a circular disk to mark the center of your scale, you can supply an Image. The image is scaled to the radius of the center object if setScaleImage() is true. In this case resizing the gauge causes a proportionate change in the image. See Sample Code for an example.

Controlling visibility

Use the visible parameter in the constructor to control whether the Center object is visible initially. After the object is created, control its visibility using the setVisible() method.


Constructors, Properties, and Methods

Constructors

JCCenter has three constructors. The one-parameter version requires a reference to the parent JCCircularGauge. The other two require a color parameter and either a size parameter in the case of a circular disk, or an image parameter if an image is to be used.

	JCCenter(JCCircularGauge gauge)
	// Creates a drawn, black center disk using a default radius 
	// that is 20% of the scale's radius.
 
	JCCenter(JCCircularGauge gauge, java.awt.Color foreground,
		 	 double radius) // Center is a disk
 
	JCCenter(JCCircularGauge gauge, java.awt.Color foreground,
			 java.awt.Image image) // Center is an image

Properties

Property Description

getImage()

setImage()

Determines the java.awt.Image that is to be drawn at the center of the scale.

getRadius()

setRadius()

Gets or sets the size parameter for the center object when it is a circular disk.

getScaleImage()

setScaleImage()

Scales the image according to the radius.

Methods

Protected methods drawDisc() and drawImage() are used to draw the Center, and are used by paintComponent() to actually draw the center object on the screen. getPreferredSize() is overridden so that the center object's proportional size relative to the circular scale can be maintained. These methods are only of concern to those who wish to subclass the Center for custom purposes.


Sample Code

Follow the first of these examples if you want to mark the center of circular scale with a colored disk and the second if you wish to supply an image.

	// create a center
	JCCenter center = new JCCenter(scale, Color.white, 0.1);
	gauge.setCenter(center);
 
	// use an image
	Image image;
	image = Toolkit.getDefaultToolkit().getImage("arrow.gif");
	JCCenter center = new JCCenter(scale, Color.white, image);
	gauge.setCenter(center);


RadialConstraint and RadialLayout

Class RadialLayout uses an instance of RadialConstraint to position a component at a given angle and at a specified proportional distance from the center of the associated circular gauge. Thus, the gauge employs RadialConstraint classes to facilitate laying out gauge objects in such a way that the objects' angular positions are maintained as the gauge is resized, as well as maintaining their proper radial proportions.

It supports the placement of any component on the gauge area, not just needles, ranges, and ticks. Usually these are labels used to annotate a Circular Gauge, but they may be any JComponent, even another gauge.

Constructors

RadialConstraint has a single constructor which is passed a gauge, an extent, and an angle. The extent parameter specifies the radial distance for the placement of the component. The angle parameter specifies the angle. The center of component's bounding rectangle is placed on the gauge at the point defined by the two parameters. Typically an instance of RadialConstraint is passed via the addLabel() method in JCCircularGauge, which passes it on to an add() method that knows how use RadialLayout to position the component.

Here's an example:

	JCCircularGauge gauge = new JCCircularGauge();
	JLabel label = new JLabel("<html>Pressure (lbs/in&sup2;)");	
	gauge.addLabel(label, new RadialConstraint(gauge, 0.35, 90));


Labels

Labels are used to annotate a Circular Gauge. Any number of them may be placed anywhere within the boundaries of the gauge area using a gauge's addLabel() method, which in turn uses a RadialConstraint. Because it is a JLabel, it has user-controllable text, position, background and foreground color, images, and borders.

The mechanism that supports this functionality is the RadialConstraint class, whose constructor is RadialConstraint(JCGauge gauge, double extent, double angle) class. You specify a label's position by giving a distance from the center of the scale and an angle.

Note that there is an automatic mechanism for providing numeric labels on tick objects or for specifying labeled ticks in user-specified formats. See the section on Tick objects for a discussion of tick labels.


Notes on the Using Labels

You can choose a location within the gauge area by specifying the location of the center of the rectangle containing the RadialConstraint class.

You can choose a border type using setBorder and adjust its appearance using the various border factory methods.

One way of setting the font is by using a JLabel's ability to process HTML tags. Set a font using the <font> tag and the color using color = HTMLcolorValue within the tag. If you are adding text to a circular gauge, you can do the following:

	JLabel l1 = new JLabel("<html><font color=black>
							Start Angle = 90\u00B0");
	l1.setToolTipText("Start Angle = 90\u00B0");
	gauge.addLabel(l1, new RadialConstraint(gauge, 0.60, 15), 0);

You can control whether a text object is drawn using setVisible() and determine its visibility with isVisible.

Aligning text

The lines of text within a label may be centered, or it may be right justified. If text is not centered it may appear that RadialConstraint is not positioning the text at the correct angle. In If text is not centered it may appear to be placed at the wrong angle both text areas are aligned vertically, but without the borders on the components it would appear that the lower label is not vertically aligned. Here is the code that produces this layout:

	JLabel l1 	= new JLabel(
				"<html><font color=black>
							<P ALIGN=CENTER>Start Angle <br>= 0\u00B0");
	l1.setToolTipText("Start Angle = 0\u00B0");
	l1.setBorder(new BevelBorder(BevelBorder.RAISED));
	gauge.getGaugeArea().add(l1, 
							new RadialConstraint(gauge, 0.50, 90), 0);
 
	JLabel l2 	= new JLabel(
			"<html><font color=black><P>Stop Angle <br>= 360\u00B0");
	l2.setToolTipText("Stop Angle = 360\u00B0");
	l2.setBorder(new BevelBorder(BevelBorder.RAISED));
	gauge.getGaugeArea().add(l2, 
							new RadialConstraint(gauge, 0.50, 270), 0);

 

If text is not centered it may appear to be placed at the wrong angle

Adding a component

A label (in reality, any JComponent) is an independent rectangular region that can be placed anywhere within the gauge area by specifying the center of the component using the RadialConstraint class.


Sample Code

The first code snippet shows the addition of a label positioned half way from the center of a gauge to its circumference at an angle of 45°.

	RadialConstraint rConstraint = new RadialConstraint(gauge, 0.50, 45)
	JLabel label 	= new JLabel("Start Angle = 0");
	label.setToolTipText("Start Angle = 0\u00B0");
	gauge.getGaugeArea().add(label, rContstraint, 0);

This one shows how to label tick marks with a string that specifies the units of the measurement. It uses the JCLabelGenerator interface and its method, makeLabel().

// create a label generator to mark ticks with their units
   	    tick.setLabelGenerator(new JCLabelGenerator() {
   	    		public JComponent makeLabel(JCTick tick, double value,
   	    			RadialConstraint constraint) {
   	    			String s = String.valueOf((int) value) + " units";
   	            JLabel label = new JLabel(s);
   	            label.setToolTipText(s);
   	    			return label;
   	    		}
       });


Events and Listeners in JCGauge

JCPickEvent represents a pick event in JCGauge. A pick event occurs when a JCPickListener is installed on a gauge and the mouse button is pressed over a JCGauge object.

Method Description

getComponent()

The component associated with this event.

getGauge()

Returns the gauge associated with this event.

getPoint()

Returns the (x, y) point of the click.

getValue()

The value associated with this event. This is the scale value corresponding to the place where the mouse click occurred.

toString()

Returns the point where the mouse was clicked and the associated scale value.

Interface JCGaugePickListener has one method, pick(). It is called on the object that has installed itself as a listener by invoking gauge.addPickListener().

See GaugePickExample.java for an example of the use of a pick listener.


Utility Functions for JCCircularGauge

Static utility functions are found in com.klg.jclass.swing.gauge.GaugeUtil. They perform conversions needed within JCCircularGauge.

Method Name

Description

getExtrema()

Given a Polygon, returns its bounding Rectangle.

normalizeAngle()

Transforms its (double) argument to an angle between 0° and 360°.

rotate()

Rotates a Polygon by an amount given in degrees.

scale()

Scales a Polygon by independent amounts in the horizontal and vertical directions.

toRadians()

Transforms its (double) argument, which should be an angle in degrees, to an angle in radians.

translate()

Translate a Polygon by the amount given by x and y parameters, given as integers representing pixels.

valueToAngle()

Converts a double to an angle in degrees. Parameters are value, start_value, stop_value, start_angle, and stop_angle. The returned value is the angle that corresponds to the input value, which is interpreted as a scale value and thus should be between the min and max values for the scale.

Example: A circular scale's start_angle is 45° and its start_value is 10. Its stop_angle is 135° and its stop_value is 55°. Given a value of 20, which is between the min and max values for the scale, the function returns 65°, the angular position on the given scale for that value. Note that the input value must be within the range set by the scale.


The JCCircularGauge JavaBean

JCCircularGauge is a JavaBean whose properties may be set at design time in an IDE. The property names as they appear in an IDE are listed in Bean Properties Reference.


Adding Other Components to a Gauge

As an example of adding any JComponent to a gauge, consider a case where the need is to provide a smaller circular gauge within a larger one, such as a stopwatch whose larger scale counts off seconds and whose smaller scale indicates the number of minutes that have elapsed. In the code snippet that follows, bigGauge is the one containing the second hand and smallGauge is the one containing the minute hand. It does not show the details of setting up the properties of the two scales, but once they are configured it is easy to place the smaller gauge within the larger.

	JCCircularGauge bigGauge;
	JCCircularGauge smallGauge;
	bigGauge.addLabel(smallGauge, 
					new RadialConstraint(smallGauge, 0.35, 90), -1);

 

One circular gauge within another

1. JCCircularGauge uses a start angle and a stop angle to define the angular range, rather than employing Java's notion of a start angle and a sweep angle. For example, a scale that occupies a lower half circle has a start angle of 180° and a stop angle of 360°. Avoid the temptation to specify these two angles as 180° and 180°! See Angles In a Circular Scale for a discussion on how angles are measured in a JCCircularScale.

2. Other than being able to specify its foreground color, the circular scale contains no other visual information. Values are marked off using tick objects and needles have a value based on their location on a scale.

3. In Java 1.1, pie shapes (filled arcs) may be drawn with one call to fillArc(), but not bands, which require two calls. The first arc is drawn from the center to range's outer extent in the range color, then a second is drawn from the center to the inner extent in the scale's foreground color. In Java 1.2, Graphics2D methods may be employed to draw a region like that shown in Layering ranges on a scale without the need to draw filled arcs radiating from the center of the scale.


[Home]   [Contents]   [Index]   [Javadoc] Comments on the documentation?
Please send them to jclass_docs@klgroup.com
[Previous]   [Next]
[Frames]    [No Frames]

Copyright © 1999 KL Group Inc.