Hello Oliver,
at the risk of confusing you, I have simplified one of our classes
to provide you with a signal-strength scale (SignalStrengthScale.java)
I haven't tested the code (at least you don't have to worry about
compile-time errors), so I can't guarantee that it will work for you.
It assumes that your function type is:
(scanNumber, frequency) --> (signal-strength)
and the constructor takes a scalar map to each of these.
This was based on a rain-rate scale that we have written. We
can change the colour of the rain-rate via a LabeledColorWidget,
and when we do, the data as well as the rain-rate scale update.
Even if the code doesn't work for you, I hope you can get some
ideas from it.
Hope this helps,
Jim.
---
Jim Koutsovasilis
Bureau of Meteorology, Australia
jimk@xxxxxxxxxx
Oliver Mather wrote:
Hi there,
I have an image plot which shows the magnitude of the data using an RGB
map. http://mcba5.phys.unsw.edu.au:8180/~oliverm/ImagePlot.jpg
The user can modify the ranges of the plot scales, thus dynamically
changing the value each colour represents.
I?d like to add a colour scale next to the plot so that it always shows
the correct values the colous represents.This is because in most cases
the plot is saved as a GIF and printed for analysis later?
Is there a builtin feature of visad to do this ?
Thanks,
Oliver Mather
Software Engineer
Ph 04040 71153
omather@xxxxxxxxxx
// SignalStrengthScale.java
// Java
import java.awt.Component;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.geom.Point2D;
import java.rmi.RemoteException;
import java.util.Vector;
import java.util.prefs.Preferences;
import javax.swing.Icon;
import javax.swing.JComponent;
// VisAD
import visad.ColorAlphaControl;
import visad.ConstantMap;
import visad.DataReferenceImpl;
import visad.Display;
import visad.DisplayEvent;
import visad.DisplayImpl;
import visad.DisplayListener;
import visad.DisplayRenderer;
import visad.FieldImpl;
import visad.FunctionType;
import visad.Gridded2DDoubleSet;
import visad.Linear1DSet;
import visad.MouseBehavior;
import visad.Real;
import visad.RealType;
import visad.RealTupleType;
import visad.ScalarMap;
import visad.Set;
import visad.ShapeControl;
import visad.Text;
import visad.TextControl;
import visad.TextType;
import visad.VisADException;
import visad.VisADRay;
import visad.VisADGeometryArray;
import visad.VisADTriangleArray;
import visad.java3d.DefaultRendererJ3D;
import visad.java3d.DisplayRendererJ3D;
import visad.java3d.MouseBehaviorJ3D;
import visad.java3d.ProjectionControlJ3D;
import visad.util.ColorChangeEvent;
import visad.util.ColorChangeListener;
import visad.util.ColorMap;
import visad.util.LabeledColorWidget;
/**
* Provides a signal strength scale for the function type:
* (scan number, frequency)->(signal strength)
*
* The scale is drawn in the lower-left corner of the display.
*/
public final class SignalStrengthScale
{
/**
* The z value (height) of this layer.
*/
private double zValue = -0.01;
/**
* The visad display we'll be adding this layer to.
*/
private DisplayImpl display;
/**
* This data renderer for the scale.
*/
private DefaultRendererJ3D scaleRenderer;
/**
* Maintains a reference to the visad data.
*/
private DataReferenceImpl dataRef;
/**
* The frequency scalar map.
*/
private ScalarMap frequencyMap;
/**
* The scan-number scalar map.
*/
private ScalarMap scanNumberMap;
/**
* The signal-strength scalar map.
*/
private ScalarMap signalStrengthMap;
/**
* The shape scalar map
*/
private ScalarMap shapeMap;
/**
* The domain type (lat,lon)
*/
private RealTupleType domainType;
/**
* The range type (shapeType)
*/
private RealType shapeType;
/**
* If true, the first Display.TRANSFORM_DONE event has occurred.
*/
private boolean firstTransformDone = false;
/**
* If true, the first Display.FRAME_DONE event has occurred.
*/
private boolean firstFrameDone = false;
/**
* The width of the scale, as a percentage of the screen's width.
*/
private float widthRatio = 0.35f;
/**
* The height of the scale, as a percentage of the screen's height.
*/
private float heightRatio = 0.03f;
/**
* The offset from the screen corner for the signal-strength scale
*/
private int offset = 10;
/**
* Holds the data coordinates (lat/lon) for the scale and its
* labels.
*/
private DataCoords dataCoords;
/**
* The font size to use for the scale's labels.
*/
private int fontSize = 6;
/**
* The font to use for the scale's labels.
*/
private String fontName = "Fast Font";
/**
* Holds data relating to the left-aligned labels.
*/
private LabelType leftAlignedLabelType;
/**
* Holds data relating to the centred labels.
*/
private LabelType centredLabelType;
/**
* Holds data relating to the right-aligned labels.
*/
private LabelType rightAlignedLabelType;
/**
* Listens for changes to the Display.RGBA scalar map.
*/
private ColourListener colourChangeListener;
/**
* This triangle array defines the signal-strength scale.
*/
private VisADTriangleArray triangleArray;
/**
* Listens for changes to the visad window's size.
*/
private CanvasResizeListener canvasResizeListener;
/**
* If true, the visad window has been resized.
*/
private boolean resizedCanvas = false;
/**
* The number of canvas resize events we are going to process.
*/
private int numCanvasResizeEvents = 0;
/**
* Constructor.
*
* @param display the visad display that this layer will be added to
* @param frequencyMap the frequency scalar map
* @param scanNumberMap the scan-number scalar map
* @param signalStrenthMap the signal-strength scalar map
*
* @throws VisADException there's a problem with VisAD
* @throws RemoteException there's a problem with VisAD
*/
public SignalStrengthScale(final Display display,
final ScalarMap scanNumberMap, final ScalarMap frequencyMap,
final ScalarMap signalStrengthMap)
throws VisADException, RemoteException
{
this.display = (DisplayImpl) display;
this.frequencyMap = frequencyMap;
this.scanNumberMap = scanNumberMap;
this.signalStrengthMap = signalStrengthMap;
domainType = RealTupleType.LatitudeLongitudeTuple;
shapeType = RealType.getRealType("colour_shape");
leftAlignedLabelType = LabelType.createLeftAligned();
centredLabelType = LabelType.createCentred();
rightAlignedLabelType = LabelType.createRightAligned();
dataRef = new DataReferenceImpl("signalstrengthscale_data_ref");
colourChangeListener = new ColourListener();
LabeledColorWidget colourWidget =
new LabeledColorWidget(signalStrengthMap);
final ColorMap colourMap = colourWidget.getBaseMap();
colourMap.addColorChangeListener(colourChangeListener);
colourWidget = null;
final DisplayRendererJ3D displayRenderer = (DisplayRendererJ3D)
this.display.getDisplayRenderer();
final Component canvas = displayRenderer.getCanvas();
canvasResizeListener = new CanvasResizeListener();
canvas.addComponentListener(canvasResizeListener);
} // SignalStrengthScale.SignalStrengthScale()
/**
* Add scalar maps to the display
*
* @param display scalar maps are added to this display.
*
* @throws RemoteException there's a problem with VisAD
* @throws VisADException there's a problem with VisAD
*/
public void addScalarMaps(Display display)
throws RemoteException, VisADException
{
shapeMap = new ScalarMap(shapeType, Display.Shape);
display.addMap(shapeMap);
display.addMap(leftAlignedLabelType.map);
display.addMap(centredLabelType.map);
display.addMap(rightAlignedLabelType.map);
TextControl control = (TextControl)
leftAlignedLabelType.map.getControl();
control.setVerticalJustification(TextControl.Justification.TOP);
control.setJustification(TextControl.Justification.LEFT);
control = (TextControl) centredLabelType.map.getControl();
control.setVerticalJustification(TextControl.Justification.TOP);
control.setJustification(TextControl.Justification.CENTER);
control = (TextControl) rightAlignedLabelType.map.getControl();
control.setVerticalJustification(TextControl.Justification.TOP);
control.setJustification(TextControl.Justification.RIGHT);
((DisplayImpl) display).addDisplayListener(
new DisplayChangedListener());
} // SignalStrengthScale.addScalarMaps()
/**
* Add data references from the display.
*
* @param display data references are added to this display.
*
* @throws RemoteException there's a problem with VisAD
* @throws VisADException there's a problem with VisAD
*/
public void addDataReferences(Display display)
throws RemoteException, VisADException
{
// Add the scale data reference to the display.
ConstantMap [] maps = new ConstantMap [] {
new ConstantMap(zValue, Display.ZAxis)
};
scaleRenderer = new DefaultRendererJ3D();
display.addReferences(scaleRenderer, dataRef, maps);
// Add the scale labels data reference to the display.
maps = new ConstantMap [] {
new ConstantMap(zValue, Display.ZAxis),
new ConstantMap(0, Display.Red),
new ConstantMap(0, Display.Green),
new ConstantMap(0, Display.Blue),
};
leftAlignedLabelType.renderer =
new DefaultRendererJ3D();
display.addReferences(leftAlignedLabelType.renderer,
leftAlignedLabelType.dataRef, maps);
maps = new ConstantMap [] {
new ConstantMap(zValue, Display.ZAxis),
new ConstantMap(0, Display.Red),
new ConstantMap(0, Display.Green),
new ConstantMap(0, Display.Blue),
};
centredLabelType.renderer =
new DefaultRendererJ3D();
display.addReferences(centredLabelType.renderer,
centredLabelType.dataRef, maps);
maps = new ConstantMap [] {
new ConstantMap(zValue, Display.ZAxis),
new ConstantMap(0, Display.Red),
new ConstantMap(0, Display.Green),
new ConstantMap(0, Display.Blue),
};
rightAlignedLabelType.renderer =
new DefaultRendererJ3D();
display.addReferences(rightAlignedLabelType.renderer,
rightAlignedLabelType.dataRef, maps);
} // SignalStrengthScale.addDataReferences()
/**
* Retrieves the data values that correspond to the specified
* screen location.
*
* @param mouseBehaviour the display renderer's mouse behavior
* @param screenX the screen X coordinate
* @param screenY the screen Y coordinate
* @param latlon used to store the result; can be null.
*
* @return the data values that correspond to the specified
* screen location.
*/
private Point2D.Double screenToDataCoords(
final MouseBehavior mouseBehaviour, final int screenX,
final int screenY, Point2D.Double latLon)
{
final VisADRay ray = mouseBehaviour.findRay(screenX, screenY);
final double [] cursor = new double[3];
// X
cursor[0] = ray.position[0];
// Y
cursor[1] = ray.position[1];
// Z
cursor[2] = ray.position[2];
final double [] dummy1 = new double[2];
final double [] dummy2 = new double[2];
final double [] scaleOffset = new double[2];
scanNumberMap.getScale(scaleOffset, dummy1, dummy2);
final double lon = (cursor[0] - scaleOffset[1]) /
scaleOffset[0];
frequencyMap.getScale(scaleOffset, dummy1, dummy2);
final double lat = (cursor[1] - scaleOffset[1]) /
scaleOffset[0];
if (null == latLon) {
latLon = new Point2D.Double();
}
latLon.x = lon;
latLon.y = lat;
return latLon;
} // SignalStrengthScale.screenToDataCoords()
/**
* Creates a visad triangle array for the signal strength scale.
*
* @param height the height of the scale
* @param width the width of the scale
*
* @return a visad triangle array that makes up the signal strength
* scale
* @throws VisADException there's a problem with VisAD
* @throws RemoteException there's a problem with VisAD
*/
private VisADTriangleArray createTriangles(final float height,
final float width) throws VisADException, RemoteException
{
// Get the colour table used by the signalStrength scalar map.
final ColorAlphaControl colourControl =
(ColorAlphaControl) signalStrengthMap.getControl();
final float [][] colourTable = colourControl.getTable();
final int numColours = colourTable[0].length;
final float delta = width / (float) numColours;
final int numPointsPerTriangle = 3;
final int numValuesPerPoint = 3;
final int numTriangles = numColours * 2;
final float [] triangles = new float[numTriangles *
numPointsPerTriangle * numValuesPerPoint];
final byte [] colours = new byte[numTriangles *
numPointsPerTriangle * numValuesPerPoint];
int index = 0;
int colourIndex = 0;
for (int i = 0; i < numColours; ++i) {
final byte red = (byte) (colourTable[0][i] * 255);
final byte green = (byte) (colourTable[1][i] * 255);
final byte blue = (byte) (colourTable[2][i] * 255);
// The right-half triangle
// 1 2
// .......
// . .
// . .
// . .
// . .
// ..
// .
// 3
// First point in triangle
triangles[index++] = delta * i;
triangles[index++] = 0.0f;
triangles[index++] = 0.0f;
colours[colourIndex++] = red;
colours[colourIndex++] = green;
colours[colourIndex++] = blue;
// Second point in triangle
triangles[index++] = (delta * i) + delta;
triangles[index++] = 0.0f;
triangles[index++] = 0.0f;
colours[colourIndex++] = red;
colours[colourIndex++] = green;
colours[colourIndex++] = blue;
// Third point in triangle
triangles[index++] = (delta * i) + delta;
triangles[index++] = height;
triangles[index++] = 0.0f;
colours[colourIndex++] = red;
colours[colourIndex++] = green;
colours[colourIndex++] = blue;
// The left-half triangle
// 1
// .
// ..
// . .
// . .
// . .
// . .
// .......
// 3 2
// First point in triangle
triangles[index++] = delta * i;
triangles[index++] = 0.0f;
triangles[index++] = 0.0f;
colours[colourIndex++] = red;
colours[colourIndex++] = green;
colours[colourIndex++] = blue;
// Second point in triangle
triangles[index++] = (delta * i) + delta;
triangles[index++] = height;
triangles[index++] = 0.0f;
colours[colourIndex++] = red;
colours[colourIndex++] = green;
colours[colourIndex++] = blue;
// Third point in triangle
triangles[index++] = delta * i;
triangles[index++] = height;
triangles[index++] = 0.0f;
colours[colourIndex++] = red;
colours[colourIndex++] = green;
colours[colourIndex++] = blue;
} // for (i<numColours)
// Set all the normal vectors to (0,0,1) for each
// vertex of each triangle.
final float [] normals = new float[numTriangles *
numPointsPerTriangle * numValuesPerPoint];
index = 0;
for (int i = 0; i < numTriangles; ++i) {
// First point in triangle.
normals[index++] = 0.0f;
normals[index++] = 0.0f;
normals[index++] = 1.0f;
// Second point in triangle.
normals[index++] = 0.0f;
normals[index++] = 0.0f;
normals[index++] = 1.0f;
// Third point in triangle.
normals[index++] = 0.0f;
normals[index++] = 0.0f;
normals[index++] = 1.0f;
} // for (i<numTriangles)
final VisADTriangleArray triangleArray
new VisADTriangleArray();
triangleArray.coordinates = triangles;
triangleArray.normals = normals;
triangleArray.colors = colours;
triangleArray.vertexCount = numTriangles * numPointsPerTriangle;
return triangleArray;
} // SignalStrengthScale.createTriangles()
/**
* Allows us to listen to Display events.
*/
private class DisplayChangedListener implements DisplayListener
{
/**
* A display changed event has occurred, so determine
* if we can draw the scale.
*
* @param event contains information about this event
*
* @throws VisADException there's a problem with VisAD
* @throws RemoteException there's a problem with VisAD
*/
public void displayChanged(DisplayEvent event)
throws VisADException, RemoteException
{
switch (event.getId()) {
case DisplayEvent.FRAME_DONE:
if (!firstTransformDone) {
return;
}
if (!firstFrameDone) {
redraw();
firstFrameDone = true;
return;
}
if (resizedCanvas) {
// The canvas has been resized
// and there are more events to
// process.
--numCanvasResizeEvents;
if (0 == numCanvasResizeEvents) {
resizedCanvas = false;
}
redraw();
} // if (resizedCanvas)
break;
case DisplayEvent.TRANSFORM_DONE:
firstTransformDone = true;
break;
case DisplayEvent.MOUSE_RELEASED_LEFT:
// The user has zoomed or panned, so
// redraw the scale.
redraw();
break;
} // switch()
} // DisplayChangedListener.displayChanged()
} // class SignalStrengthScale.DisplayChangedListener
/**
* Creates the visad field and all the data that is used
* by the signal strength scale.
*
* @return a visad field that contains all the scale data
*
* @throws VisADException there's a problem with VisAD
* @throws RemoteException there's a problem with VisAD
*/
private FieldImpl createField() throws VisADException, RemoteException
{
final double deltaLat = Math.abs(
dataCoords.bottomRightOfScale.y -
dataCoords.topLeftOfScale.y);
final double deltaLon = Math.abs(
dataCoords.bottomRightOfScale.x -
dataCoords.topLeftOfScale.x);
// This scale was found experimentally, and it seems
// to work well for all occassions.
final float scale = 0.0055f;
/*
final VisADTriangleArray triangleArray
createTriangles((float) deltaLat * scale,
(float) deltaLon * scale);
*/
triangleArray = createTriangles((float) deltaLat * scale,
(float) deltaLon * scale);
// Setup the shape control with the new triangle array shape.
final ShapeControl shapeControl =
(ShapeControl) shapeMap.getControl();
shapeControl.setShapeSet(new Linear1DSet(0, 1, 1));
final VisADGeometryArray [] shapes = new VisADGeometryArray[] {
triangleArray };
shapeControl.setShapes(shapes);
// Place the shape at the lower left corner of the screen.
final double [][] domainSamples = new double[2][1];
domainSamples[0][0] = dataCoords.bottomRightOfScale.y;
domainSamples[1][0] = dataCoords.topLeftOfScale.x;
final Set domainSet = new Gridded2DDoubleSet(domainType,
domainSamples, 1);
final FunctionType functionType = new FunctionType(
domainType, shapeType);
final FieldImpl field = new FieldImpl(functionType, domainSet);
field.setSample(0, new Real(shapeType, 0));
return field;
} // SignalStrengthScale.createField()
/**
* Creates the field and data for the scale labels.
*
* @throws VisADException there's a problem in VisAD
* @throws RemoteException there's a problem in VisAD
*/
private void setupLabelData()
throws VisADException, RemoteException
{
double [][] domainSamples = new double[2][1];
domainSamples[0][0] = dataCoords.leftLabel.y;
domainSamples[1][0] = dataCoords.leftLabel.x;
Gridded2DDoubleSet domainSet = new Gridded2DDoubleSet(
domainType, domainSamples, 1);
FunctionType functionType = new FunctionType(domainType,
leftAlignedLabelType.type);
FieldImpl field = new FieldImpl(functionType, domainSet);
field.setSample(0, new Text(leftAlignedLabelType.type,
"Light"));
leftAlignedLabelType.dataRef.setData(field);
domainSamples[0][0] = dataCoords.centreLabel.y;
domainSamples[1][0] = dataCoords.centreLabel.x;
domainSet = new Gridded2DDoubleSet(domainType,
domainSamples, 1);
functionType = new FunctionType(domainType,
centredLabelType.type);
field = new FieldImpl(functionType, domainSet);
field.setSample(0, new Text(centredLabelType.type,
"Moderate"));
centredLabelType.dataRef.setData(field);
domainSamples[0][0] = dataCoords.rightLabel.y;
domainSamples[1][0] = dataCoords.rightLabel.x;
domainSet = new Gridded2DDoubleSet(domainType,
domainSamples, 1);
functionType = new FunctionType(domainType,
rightAlignedLabelType.type);
field = new FieldImpl(functionType, domainSet);
field.setSample(0, new Text(rightAlignedLabelType.type,
"Heavy"));
rightAlignedLabelType.dataRef.setData(field);
formatLabels();
} // SignalStrengthScale.setupLabelData()
/**
* Setup the data coordinates for the scale and its labels.
*/
private DataCoords setupDataCoords()
{
// ........................................
// . .
// ........................................
// | | |
// Light Moderate Heavy
//
//
final Rectangle screenRect = display.getComponent().getBounds();
final int labelOffset = 5;
final int scaleWidth = (int) (screenRect.width * widthRatio);
final int scaleHeight = (int) (screenRect.height * heightRatio);
final int left = offset;
final int right = left + scaleWidth;
final int labelTop = screenRect.height - offset -
(2 * fontSize);
final int labelCentre = left + ((right - left) / 2);
final int labelLeft = left;
final int labelRight = right;
final int bottom = labelTop - labelOffset;
final int top = bottom - scaleHeight;
final DisplayRenderer displayRenderer =
display.getDisplayRenderer();
final MouseBehavior mouseBehaviour =
displayRenderer.getMouseBehavior();
final Point2D.Double topLeft = screenToDataCoords(
mouseBehaviour,
left, top, null);
final Point2D.Double bottomRight = screenToDataCoords(
mouseBehaviour, right, bottom, null);
final DataCoords coordinates = new DataCoords();
coordinates.topLeftOfScale = screenToDataCoords(mouseBehaviour,
left, top, null);
coordinates.bottomRightOfScale = screenToDataCoords(
mouseBehaviour, right, bottom, null);
coordinates.leftLabel = screenToDataCoords(mouseBehaviour,
labelLeft, labelTop, null);
coordinates.centreLabel = screenToDataCoords(mouseBehaviour,
labelCentre, labelTop, null);
coordinates.rightLabel = screenToDataCoords(mouseBehaviour,
labelRight, labelTop, null);
return coordinates;
} // SignalStrengthScale.setupDataCoords()
/**
* Wraps up the data coordinates (lat,lon) of the scale
* and its labels.
*/
private static class DataCoords
{
/**
* The top left corner of the scale.
*/
private Point2D.Double topLeftOfScale;
/**
* The bottom right corner of the scale.
*/
private Point2D.Double bottomRightOfScale;
/**
* The coordinate of the "Light" label.
*/
private Point2D.Double leftLabel;
/**
* The corrdinate of the "Moderate" label.
*/
private Point2D.Double centreLabel;
/**
* The coordinate of the "Heavy" label.
*/
private Point2D.Double rightLabel;
} // class SignalStrengthScale.DataCoords
/**
* Formats the labels so they are centred, top justified, and
* have a small font size.
*
* @throws VisADException there's a problem with VisAD
* @throws RemoteException there's a problem with VisAD
*/
private void formatLabels() throws VisADException, RemoteException
{
// To set the correct font size, we have to undo
// the current level of zoom, and then set our
// font size.
final ProjectionControlJ3D projectionControl =
(ProjectionControlJ3D)
this.display.getProjectionControl();
final double [] scale = new double[1];
final double [] translation = new double[3];
final double [] rotation = new double[3];
MouseBehaviorJ3D.unmake_matrix(rotation, scale,
translation, projectionControl.getMatrix());
final double baseFontSize = 14;
Font font = null;
if (!fontName.equals("Fast Font")) {
font = new Font(fontName, Font.PLAIN, fontSize);
}
TextControl textControl = (TextControl)
leftAlignedLabelType.map.getControl();
textControl.setSize((fontSize / baseFontSize) / scale[0]);
textControl.setFont(font);
textControl = (TextControl)
centredLabelType.map.getControl();
textControl.setSize((fontSize / baseFontSize) / scale[0]);
textControl.setFont(font);
textControl = (TextControl)
rightAlignedLabelType.map.getControl();
textControl.setSize((fontSize / baseFontSize) / scale[0]);
textControl.setFont(font);
} // SignalStrengthScale.formatLabels()
/**
* Wraps up data for a particularly-aligned Text control.
*/
private static class LabelType
{
/**
* Creates a left-aligned label type.
*
* @throws VisAException there's a problem with VisAD
*/
public static LabelType createLeftAligned()
throws VisADException
{
return new LabelType(TextControl.Justification.LEFT);
} // LabelType.createLeftAligned()
/**
* Creates a centred label type.
*
* @throws VisAException there's a problem with VisAD
*/
public static LabelType createCentred()
throws VisADException
{
return new LabelType(TextControl.Justification.CENTER);
} // LabelType.createCentred()
/**
* Creates a right-aligned label type.
*
* @throws VisAException there's a problem with VisAD
*/
public static LabelType createRightAligned()
throws VisADException
{
return new LabelType(TextControl.Justification.RIGHT);
} // LabelType.createRightAligned()
/**
* Private constructor means only factory methods can
* create an instance of this class.
*
* @param justification the horizontal justification for
* this label.
* @throws VisADException there's a problem with VisAD
*/
private LabelType(TextControl.Justification justification)
throws VisADException
{
String name = null;
if (TextControl.Justification.LEFT == justification) {
name = "left-aligned";
} else if (TextControl.Justification.CENTER =
justification)
{
name = "centred";
} else if (TextControl.Justification.RIGHT =
justification)
{
name = "right-aligned";
} else {
throw new IllegalArgumentException(
"Bad type of horizontal justification");
}
type = TextType.getTextType(name);
map = new ScalarMap(type, Display.Text);
dataRef = new DataReferenceImpl(name);
} // LabelTypel.LabelType()
/**
* The text type for this type of label.
*/
private TextType type;
/**
* The scalar map that maps "type" to Display.Text
*/
private ScalarMap map;
/**
* The data reference.
*/
private DataReferenceImpl dataRef;
/**
* The label's renderer.
*/
private DefaultRendererJ3D renderer;
} // class SignalStrengthScale.LabelType
/**
* Listens for colour changes in the scalar map:
* RealType.signalStrength --> Display.RGBA
*/
private class ColourListener implements ColorChangeListener
{
/**
* The colour table has changed, so update the signal-strength
* scale.
*/
public synchronized void colorChanged(ColorChangeEvent event)
{
if (firstFrameDone) {
Exception exception = null;
try {
redraw();
} catch (VisADException ex) {
exception = ex;
} catch (RemoteException ex) {
exception = ex;
}
if (exception != null) {
System.err.println(
"SignalStrengthScale." +
"ColourListener.colorChanged:" +
" could not update colours");
}
} // if (firstFrameDone)
} // ColourListener.colorChanged()
} // class SignalStrengthScale.ColourListener
/**
* When the visad window is resized, we need to redraw the
* signal-strength scale.
*/
private class CanvasResizeListener extends ComponentAdapter
{
/**
* The visad window has been resized, so redraw.
*/
public synchronized void componentResized(ComponentEvent event)
{
if (!firstFrameDone) {
// We're not ready to handle resize events
// just yet.
return;
}
// We'll process the first two FRAME_DONE events
numCanvasResizeEvents = 2;
resizedCanvas = true;
} // CanvasResizeListener.componentResized()
} // class SignalStrengthScale.CanvasResizeListener
/**
* Redraws the signal-strength scale and the labels.
*
* @throws VisADException there's a problem in VisAD
* @throws RemoteException there's a problem in VisAD
*/
private synchronized void redraw()
throws VisADException, RemoteException
{
dataCoords = setupDataCoords();
dataRef.setData(createField());
setupLabelData();
} // SignalStrengthScale.redraw()
} // class SignalStrengthScale