1

I have difficulties drawing an image on a JFreeChart - XYLineChart. The main problem is the x and y coordinates of the annotation is updated dynamically in real time.So with my code adding the annotation and clearing it for the new one to be drawn causes flickering which is annoying for the user.

I have checked some examples of flickering problems on JAVA using update() , paint () or repaint() methods using graphics but seems not implementable on a JFreeChart.

Do you have any ideas how to get rid of the flicker or a workaround to use one bufferedImage on the JFreeChart instead of an annotation ?

To be more specific here is the drawn line and the image :

Screenshot

So this cross hair (as the buffered image) should go on the plot line up and down with the updated values of x and y axis.But this motion causes the flickering unfortunately.

Here is the part of my code where I draw the image - I cannot provide SSCCE I guess since there are more than 15 classes and 5k of written code :

// After a button clicked on panel
SomeButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent event) {

        // The chart and XYPlot is already drawn at this point 


        // Reading the image
        try {
            myPicture = ImageIO
                    .read(new File("\\\\Users2\\blabla\\Data\\MyPictures\\x.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        // Setting up a timer
        timer2 = new java.util.Timer();

        Object source = event.getSource();
        if (source == SomeButton) {

        // Setting up a task
            task2 = new java.util.TimerTask() {
                @Override
                public void run() {
                    double x1;
                    double y1;
                    try {
                        // Getting different x and y values from a microcontroller instantaneously
                        if (microContConnected()) {

                            x1 = microCont.getX();
                            y1 = microCont.getY();

                            // creating the annotation
                            XYImageAnnotation ImageAnn = new XYImageAnnotation(x1, y1, myPicture);

                            // Here is the drawing and clearing made !
                            plot.addAnnotation(ImageAnn);       
                            pause(50);
                            plot.clearAnnotations();    
                        }

                    } catch (SerialPortException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            };
            timer2.scheduleAtFixedRate(task2, 50, 50);
        }
    }
});
  • Unable to reproduce. An [sscce](http://sscce.org/) should be < 100 lines of code. Use a `Shape` or an existing `UIManager` icon for your image and a `javax.swing.Timer` for easier synchronization. – trashgod Dec 12 '12 at 18:41

1 Answers1

0

It seems I found a solution myself ; instead of adding the image to plot I use the renderer and there is no pause function between adding and removing the picture with new coordinates.. also sequence of adding and removed are reversed. Surprising for me to work this way I must say. There is no flickering left; it's as smooth as a clipped graphics or double buffered. :) Here is the new code :

    // renderer
    final XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();

    // Reading the image
    try {
        myPicture = ImageIO.read(new File("\\\\Users2\\blabla\\Data\\MyPictures\\x.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }

    // Setting up a timer
    timer2 = new java.util.Timer();

    Object source = event.getSource();
    if (source == someButton) {

                task2 = new java.util.TimerTask() {
                    @Override
                    public void run() {
                        if (check == true) {
                            if (microContConnected()) {

                                 x1 = microCont.getX();
                                 y1 = microCont.getY();

                                renderer.removeAnnotations();

                                XYImageAnnotation img2 = new XYImageAnnotation(
                                        x1, y1, myPicture);
                                renderer.addAnnotation(img2,
                                        Layer.FOREGROUND);
                            }
                        }
                    }
                };
                timer2.scheduleAtFixedRate(task2, 50, 50);
            }