ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

java-Jfreechart注释消失

2019-10-13 23:03:46  阅读:282  来源: 互联网

标签:java jfreechart annotations


我用JFreechart绘制了一条曲线.然后,用户可以通过拖动鼠标来绘制范围.这些我使用AbstractChartAnnotation绘制以绘制填充的Path2D.到目前为止,一切都很好-都与曲线完美对齐.

当一个区域已经被注释时,新的注释将被删除.我将XYPlot.removeAnnotation与新注释一起使用.

我的问题是,有时不仅删除了“新”注释,还删除了绘图中其他地方的第二个注释.似乎不是随机的-我有点发现“右侧”的注解更容易发生这种情况.

我很困惑是什么原因造成的.每次都会恢复绘制/删除新注释的对象,并且仅保留当前注释-那么如何删除其他注释?

非常感谢您的任何提示,谢谢.

按照建议,我准备一个sscce示例.不幸的是,它并不太短.

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.*;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.event.MouseInputListener;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.AbstractXYAnnotation;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.TimeSeriesDataItem;
import org.jfree.ui.RectangleEdge;

/**
 *
 * @author c.ager
 */
public class IntegrationSSCE {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        JFrame jFrame = new JFrame();
        jFrame.setLayout(new BorderLayout());
        jFrame.setSize(600, 400);
        jFrame.setDefaultCloseOperation(jFrame.EXIT_ON_CLOSE);
        TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection();
        TimeSeries timeSeries = new TimeSeries("test");
        for (long i = 0; i < 1000; i++) {
            double val = Math.random() + 3 * Math.exp(-Math.pow(i - 300, 2) / 1000);
            timeSeries.add(new Millisecond(new Date(i)), val);
        }
        timeSeriesCollection.addSeries(timeSeries);

        JFreeChart chart = ChartFactory.createTimeSeriesChart(
                null,
                null, "data", timeSeriesCollection,
                true, true, false);
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.removeMouseListener(chartPanel);

        Set<MyAnnot> annotSet = new TreeSet<MyAnnot>();

        AnnotListener list = new AnnotListener(chartPanel, annotSet, timeSeries);
        chartPanel.addMouseListener(list);
        chartPanel.addMouseMotionListener(list);

        jFrame.add(chartPanel, BorderLayout.CENTER);


        jFrame.setVisible(true);

        // TODO code application logic here
    }

    private static class AnnotListener implements MouseInputListener {

        Point2D start, end;
        MyAnnot currAnnot;
        final Set<MyAnnot> annotSet;
        final ChartPanel myChart;
        final TimeSeries timeSeries;

        public AnnotListener(ChartPanel myChart, Set<MyAnnot> annotSet, TimeSeries timeSeries) {
            this.myChart = myChart;
            this.annotSet = annotSet;
            this.timeSeries = timeSeries;
        }

        @Override
        public void mousePressed(MouseEvent e) {
            start = convertScreePoint2DataPoint(e.getPoint());
            currAnnot = new MyAnnot(start, timeSeries, myChart.getChart().getXYPlot());
            myChart.getChart().getXYPlot().addAnnotation(currAnnot);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            end = convertScreePoint2DataPoint(e.getPoint());
            currAnnot.updateEnd(end);
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            boolean test = annotSet.add(currAnnot);
            if (!test) {
                myChart.getChart().getXYPlot().removeAnnotation(currAnnot);
            }
        }

        @Override
        public void mouseEntered(MouseEvent e) {
        }

        @Override
        public void mouseClicked(MouseEvent e) {
        }

        @Override
        public void mouseExited(MouseEvent e) {
        }

        @Override
        public void mouseMoved(MouseEvent e) {
        }

        protected Point2D convertScreePoint2DataPoint(Point in) {
            Rectangle2D plotArea = myChart.getScreenDataArea();
            XYPlot plot = (XYPlot) myChart.getChart().getPlot();
            double x = plot.getDomainAxis().java2DToValue(in.getX(), plotArea, plot.getDomainAxisEdge());
            double y = plot.getRangeAxis().java2DToValue(in.getY(), plotArea, plot.getRangeAxisEdge());
            return new Point2D.Double(x, y);
        }
    }

    private static class MyAnnot extends AbstractXYAnnotation implements Comparable<MyAnnot> {

        Long max;
        Line2D line;
        final TimeSeries timeSeries;
        final XYPlot plot;
        final Stroke stroke  = new BasicStroke(1.5f);

        public MyAnnot(Point2D start, TimeSeries timeSeries, XYPlot plot) {
            this.plot = plot;
            this.timeSeries = timeSeries;

            line = new Line2D.Double(start, start);
            findMax();
        }

        public void updateEnd(Point2D end) {
            line.setLine(line.getP1(), end);
            findMax();
            fireAnnotationChanged();
        }

        @Override
        public void draw(Graphics2D gd, XYPlot xyplot, Rectangle2D rd, ValueAxis va, ValueAxis va1, int i, PlotRenderingInfo pri) {
            PlotOrientation orientation = plot.getOrientation();
            RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
                    plot.getDomainAxisLocation(), orientation);
            RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(
                    plot.getRangeAxisLocation(), orientation);

            double m02 = va.valueToJava2D(0, rd, domainEdge);
            // y-axis translation
            double m12 = va1.valueToJava2D(0, rd, rangeEdge);
            // x-axis scale
            double m00 = va.valueToJava2D(1, rd, domainEdge) - m02;
            // y-axis scale
            double m11 = va1.valueToJava2D(1, rd, rangeEdge) - m12;

            Shape s = null;
            if (orientation == PlotOrientation.HORIZONTAL) {
                AffineTransform t1 = new AffineTransform(
                        0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f);
                AffineTransform t2 = new AffineTransform(
                        m11, 0.0f, 0.0f, m00, m12, m02);
                s = t1.createTransformedShape(line);
                s = t2.createTransformedShape(s);
            } else if (orientation == PlotOrientation.VERTICAL) {
                AffineTransform t = new AffineTransform(m00, 0, 0, m11, m02, m12);
                s = t.createTransformedShape(line);
            }
            gd.setStroke(stroke);
            gd.setPaint(Color.BLUE);
            gd.draw(s);
            addEntity(pri, s.getBounds2D(), i, getToolTipText(), getURL());
        }

        @Override
        public int compareTo(MyAnnot o) {
            return max.compareTo(o.max);
        }

        private void findMax() {
            max = (long) line.getP1().getX();

            Point2D left, right;
            if (line.getP1().getX() < line.getP2().getX()) {
                left = line.getP1();
                right = line.getP2();
            } else {
                left = line.getP2();
                right = line.getP1();
            }
            Double maxVal = left.getY();
            List<TimeSeriesDataItem> items = timeSeries.getItems();
            for (Iterator<TimeSeriesDataItem> it = items.iterator(); it.hasNext();) {
                TimeSeriesDataItem dataItem = it.next();
                if (dataItem.getPeriod().getFirstMillisecond() < left.getX()) {
                    continue;
                }
                if (dataItem.getPeriod().getFirstMillisecond() > right.getX()) {
                    break;
                }
                double curVal = dataItem.getValue().doubleValue();
                if (curVal > maxVal) {
                    maxVal = curVal;
                    max = dataItem.getPeriod().getFirstMillisecond();
                }
            }
        }
    }
}

这是有问题的行为.请注意,图像2和4是在按下鼠标按钮时拍摄的.

>选择几行不重叠的行-应该没有问题

我刚刚在调试器中查看了它-可能是ArrayList.remove(Object o)删除了WRONG元素吗?对我来说似乎不太可能…

解决方法:

您可能会查看添加了注释的Layer.有一个示例here.很自然地,一个显示您描述的问题的sscce有助于弄清楚问题的根源.

附录:一个潜在的问题是您的Comparable的实现与equals()不一致,因为后者(隐式)依赖于超类实现.要与排序集(例如TreeSet)一起使用,需要一个一致的实现.您还需要覆盖hashCode().类Value是一个示例.

标签:java,jfreechart,annotations
来源: https://codeday.me/bug/20191013/1910984.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有