001 package ui.recognizer;
002
003 import java.awt.*;
004 import javax.swing.*;
005 import static java.lang.Math.*;
006
007 public class XRule extends Rule {
008 public static final int SIZE = 35;
009
010 ImageCoordinate[] imagePoints = null; // required
011
012 public XRule(boolean isDataUnits, Calibration aCalibration, ImageCoordinate[] someImagePoints) {
013 super(isDataUnits, aCalibration);
014 imagePoints = someImagePoints;
015 }
016
017 private int xmax, xmin, ymax, ymin; // data point extrema
018
019 /** Set the data points in image coordinate representation.
020 * Used for rendering a gray image version of plot in horizontal rule.
021 * @param someImagePoints an array of recognized plot points
022 */
023 public void setImagePoints(ImageCoordinate[] someImagePoints) {
024 xmax = Integer.MIN_VALUE; // find maximum and minimum of points
025 xmin = Integer.MAX_VALUE;
026 ymax = Integer.MIN_VALUE;
027 ymin = Integer.MAX_VALUE;
028 for (ImageCoordinate point : someImagePoints) {
029 int x = (int) point.getX();
030 xmax = max(xmax, x);
031 xmin = min(xmin, x);
032 int y = (int) point.getY();
033 if (y != 0) { // zero encodes that no data is available
034 ymax = max(ymax, y);
035 ymin = min(ymin, y);
036 }
037 }
038 repaint();
039 }
040
041 public void setPreferredWidth(int pw) {
042 setPreferredSize(new Dimension(pw, SIZE));
043 }
044
045 public void paintComponent(Graphics g) {
046 Rectangle drawHere = g.getClipBounds();
047
048 // Fill clipping area with neutral gray
049 g.setColor(Color.gray);
050 g.fillRect(drawHere.x, drawHere.y, drawHere.width, drawHere.height);
051
052 // Use clipping bounds to calculate first tick and last tick location.
053
054 int start = (drawHere.x / increment) * increment;
055 int end = (((drawHere.x + drawHere.width) / increment) + 1) * increment;
056
057 // ticks and labels
058 int tickLength = 0;
059 String text = null;
060
061 if (imagePoints != null) {
062 int localymax = Integer.MIN_VALUE;
063 int localymin = Integer.MAX_VALUE;
064 for (int i = drawHere.x; i < imagePoints.length && i < (drawHere.x + drawHere.width); i++) {
065 ImageCoordinate point = imagePoints[i];
066 int y = (int) point.getY();
067 if (y != 0) {
068 localymax = max(localymax, y);
069 localymin = min(localymin, y);
070 }
071 }
072 if ((localymax - localymin) == 0) localymax = localymin+1;
073 for (int i = drawHere.x; i < imagePoints.length && i < (drawHere.x + drawHere.width); i++) {
074 ImageCoordinate point = imagePoints[i];
075 int y = (int) point.getY();
076 float intensity;
077 if (y == 0) intensity = 0.0f;
078 else intensity = (float) (localymax - y) / (float) (localymax - localymin);
079
080 if (intensity < 0.0f) intensity = 0.0f;
081 if (intensity > 1.0f) intensity = 1.0f;
082 g.setColor(new Color(intensity, intensity, intensity));
083 g.drawLine(i, 0, i, SIZE-1);
084 }
085
086 }
087
088 // Do the ruler labels in a small font that's black.
089 g.setFont(new Font("SansSerif", Font.PLAIN, 10));
090 g.setColor(Color.red);
091
092 for (int i = start; i < end; i += increment) {
093 if (i % units == 0) {
094 tickLength = 10;
095 text = Integer.toString(i/units);
096 } else {
097 tickLength = 7;
098 text = null;
099 }
100
101 if (tickLength != 0) {
102 g.drawLine(i, SIZE-1, i, SIZE-tickLength-1);
103 if (text != null) g.drawString(text, i-3, 21);
104
105 }
106 }
107 }
108 }