📄 compassplot.java
字号:
/** * Sets the needle for a series. * * @param index the series index. * @param needle the needle. */ public void setSeriesNeedle(int index, MeterNeedle needle) { if ((needle != null) && (index < this.seriesNeedle.length)) { this.seriesNeedle[index] = needle; } notifyListeners(new PlotChangeEvent(this)); } /** * Returns the dataset. * <P> * Provided for convenience. * * @return The dataset for the plot, cast as a ValueDataset. */ public ValueDataset[] getData() { return this.datasets; } /** * Adds a dataset to the compass. * * @param data the new dataset. */ public void addData(ValueDataset data) { addData(data, null); } /** * Adds a dataset to the compass. * * @param data the new dataset. * @param needle the needle. */ public void addData(ValueDataset data, MeterNeedle needle) { if (data != null) { int i = this.datasets.length + 1; ValueDataset[] t = new ValueDataset[i]; MeterNeedle[] p = new MeterNeedle[i]; i = i - 2; for (; i >= 0; --i) { t[i] = this.datasets[i]; p[i] = this.seriesNeedle[i]; } i = this.datasets.length; t[i] = data; p[i] = ((needle != null) ? needle : p[i - 1]); ValueDataset[] a = this.datasets; MeterNeedle[] b = this.seriesNeedle; this.datasets = t; this.seriesNeedle = p; for (--i; i >= 0; --i) { a[i] = null; b[i] = null; } data.addChangeListener(this); } } /** * Draws the plot on a Java 2D graphics device (such as the screen or a printer). * * @param g2 the graphics device. * @param plotArea the area within which the plot should be drawn. * @param parentState the state from the parent plot, if there is one. * @param info collects info about the drawing. */ public void draw(Graphics2D g2, Rectangle2D plotArea, PlotState parentState, PlotRenderingInfo info) { int outerRadius = 0; int innerRadius = 0; int x1, y1, x2, y2; double a; if (info != null) { info.setPlotArea(plotArea); } // adjust for insets... Insets insets = getInsets(); if (insets != null) { plotArea.setRect(plotArea.getX() + insets.left, plotArea.getY() + insets.top, plotArea.getWidth() - insets.left - insets.right, plotArea.getHeight() - insets.top - insets.bottom); } // draw the background if (this.drawBorder) { drawBackground(g2, plotArea); } int midX = (int) (plotArea.getWidth() / 2); int midY = (int) (plotArea.getHeight() / 2); int radius = midX; if (midY < midX) { radius = midY; } --radius; int diameter = 2 * radius; midX += (int) plotArea.getMinX(); midY += (int) plotArea.getMinY(); this.circle1.setFrame(midX - radius, midY - radius, diameter, diameter); this.circle2.setFrame(midX - radius + 15, midY - radius + 15, diameter - 30, diameter - 30); g2.setPaint(this.rosePaint); this.a1 = new Area(this.circle1); this.a2 = new Area(this.circle2); this.a1.subtract(this.a2); g2.fill(this.a1); g2.setPaint(this.roseCenterPaint); x1 = diameter - 30; g2.fillOval(midX - radius + 15, midY - radius + 15, x1, x1); g2.setPaint(this.roseHighlightPaint); g2.drawOval(midX - radius, midY - radius, diameter, diameter); x1 = diameter - 20; g2.drawOval(midX - radius + 10, midY - radius + 10, x1, x1); x1 = diameter - 30; g2.drawOval(midX - radius + 15, midY - radius + 15, x1, x1); x1 = diameter - 80; g2.drawOval(midX - radius + 40, midY - radius + 40, x1, x1); outerRadius = radius - 20; innerRadius = radius - 32; for (int w = 0; w < 360; w += 15) { a = Math.toRadians(w); x1 = midX - ((int) (Math.sin(a) * innerRadius)); x2 = midX - ((int) (Math.sin(a) * outerRadius)); y1 = midY - ((int) (Math.cos(a) * innerRadius)); y2 = midY - ((int) (Math.cos(a) * outerRadius)); g2.drawLine(x1, y1, x2, y2); } g2.setPaint(this.roseHighlightPaint); innerRadius = radius - 26; outerRadius = 7; for (int w = 45; w < 360; w += 90) { a = Math.toRadians(w); x1 = midX - ((int) (Math.sin(a) * innerRadius)); y1 = midY - ((int) (Math.cos(a) * innerRadius)); g2.fillOval(x1 - outerRadius, y1 - outerRadius, 2 * outerRadius, 2 * outerRadius); } /// Squares for (int w = 0; w < 360; w += 90) { a = Math.toRadians(w); x1 = midX - ((int) (Math.sin(a) * innerRadius)); y1 = midY - ((int) (Math.cos(a) * innerRadius)); Polygon p = new Polygon(); p.addPoint(x1 - outerRadius, y1); p.addPoint(x1, y1 + outerRadius); p.addPoint(x1 + outerRadius, y1); p.addPoint(x1, y1 - outerRadius); g2.fillPolygon(p); } /// Draw N, S, E, W innerRadius = radius - 42; Font f = getCompassFont(radius); g2.setFont(f); g2.drawString("N", midX - 5, midY - innerRadius + f.getSize()); g2.drawString("S", midX - 5, midY + innerRadius - 5); g2.drawString("W", midX - innerRadius + 5, midY + 5); g2.drawString("E", midX + innerRadius - f.getSize(), midY + 5); // plot the data (unless the dataset is null)... y1 = radius / 2; x1 = radius / 6; Rectangle2D needleArea = new Rectangle2D.Double((midX - x1), (midY - y1), (2 * x1), (2 * y1)); int x = this.seriesNeedle.length; int current = 0; double value = 0; int i = (this.datasets.length - 1); for (; i >= 0; --i) { ValueDataset data = this.datasets[i]; if (data != null && data.getValue() != null) { value = (data.getValue().doubleValue()) % this.revolutionDistance; value = value / this.revolutionDistance * 360; current = i % x; this.seriesNeedle[current].draw(g2, needleArea, value); } } if (this.drawBorder) { drawOutline(g2, plotArea); } } /** * Returns a short string describing the type of plot. * * @return a string describing the plot. */ public String getPlotType() { return localizationResources.getString("Compass_Plot"); } /** * Returns the legend items for the plot. For now, no legend is available - this method * returns null. * * @return the legend items. */ public LegendItemCollection getLegendItems() { return null; } /** * No zooming is implemented for compass plot, so this method is empty. * * @param percent the zoom amount. */ public void zoom(double percent) { // no zooming possible } /** * Returns the font for the compass. * * @param radius the radius. * * @return the font. */ protected Font getCompassFont(int radius) { float fontSize = radius / 10; if (fontSize < 8) { fontSize = 8; } Font newFont = this.compassFont.deriveFont(fontSize); return newFont; } /** * Returns a list of legend item labels. * * @return a list of legend item labels. * * @deprecated use getLegendItems(). */ public java.util.List getLegendItemLabels() { return null; } /** * Tests an object for equality with this plot. * * @param object the object. * * @return A boolean. */ public boolean equals(Object object) { if (object == null) { return false; } if (object == this) { return true; } if (object instanceof CompassPlot && super.equals(object)) { CompassPlot p = (CompassPlot) object; boolean b0 = (this.labelType == p.labelType); boolean b1 = ObjectUtils.equal(this.labelFont, p.labelFont); boolean b2 = (this.drawBorder == p.drawBorder); boolean b3 = ObjectUtils.equal(this.roseHighlightPaint, p.roseHighlightPaint); boolean b4 = ObjectUtils.equal(this.rosePaint, p.rosePaint); boolean b5 = ObjectUtils.equal(this.roseCenterPaint, p.roseCenterPaint); boolean b6 = ObjectUtils.equal(this.compassFont, p.compassFont); boolean b7 = Arrays.equals(this.seriesNeedle, p.seriesNeedle); boolean b8 = this.getRevolutionDistance() == p.getRevolutionDistance(); return b0 && b1 && b2 && b3 && b4 && b5 && b6 && b7 && b8; } return false; } /** * Returns a clone of the annotation. * * @return A clone. * * @throws CloneNotSupportedException this class will not throw this exception, but subclasses * (if any) might. */ public Object clone() throws CloneNotSupportedException { CompassPlot clone = (CompassPlot) super.clone(); //private int labelType <-- primitive //private Font labelFont <-- immutable //private boolean drawBorder = false <-- primitive //private Color roseHighlightColour <-- immutable //private Color roseColour <-- immutable //private Color roseCenterColour <-- immutable //private Font compassFont <-- immutable clone.circle1 = (Ellipse2D) this.circle1.clone(); clone.circle2 = (Ellipse2D) this.circle2.clone(); clone.a1 = (Area) this.a1.clone(); clone.a2 = (Area) this.a2.clone(); clone.rect1 = (Rectangle2D) this.rect1.clone(); clone.datasets = (ValueDataset[]) this.datasets.clone(); clone.seriesNeedle = (MeterNeedle[]) this.seriesNeedle.clone(); // clone share data sets => add the clone as listener to the dataset for (int i = 0; i < this.datasets.length; ++i) { if (clone.datasets[i] != null) { clone.datasets[i].addChangeListener(clone); } } return clone(); } /** * Sets the count to complete one revolution. Can be arbitaly set * For degrees (the default) it is 360, for radians this is 2*Pi, etc * * @param size the count to complete one revolution. */ public void setRevolutionDistance(double size) { if (size > 0) { this.revolutionDistance = size; } } /** * Gets the count to complete one revolution. * * @return the count to complete one revolution */ public double getRevolutionDistance() { return this.revolutionDistance; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -