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    }