Repaint() and double-buffering in java8, bug?

289 views Asked by At

I've been playing with animation in Swing on Java 8 and have encountered some strange behaviour: sometimes content of a component suddenly becomes stale after calling repaint() on some other unrelated component. Below is the code, which reproduces this behaviour for me:

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;

public class Crosshair extends JPanel {
    private int currentMouseX = 0;
    private int currentMouseY = 0;

    public Crosshair() {
        addMouseMotionListener(new MouseAdapter() {
            @Override
            public void mouseMoved(MouseEvent e) {
                currentMouseX = e.getX();
                currentMouseY = e.getY();
                repaint();
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.red);
        g.drawLine(currentMouseX, 0, currentMouseX, getHeight() - 1);
        g.drawLine(0, currentMouseY, getWidth() - 1, currentMouseY);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame f = new JFrame("Test frame");
            f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            Box content = Box.createHorizontalBox();
            content.add(new Crosshair());
            content.add(new JButton("Just filler between"));
            content.add(new Crosshair());
            f.getContentPane().add(content);
            f.setSize(new Dimension(500, 200));
            //Bug goes away if double buffering is switched off
            //RepaintManager.currentManager(f).setDoubleBufferingEnabled(false);
            f.setVisible(true);
        });
    }
}

Steps to reproduce:

  1. Run this, see how crosshairs follow the cursor.
  2. Resize window by dragging right window border
  3. Hover the mouse over right crosshair, see how it follows the cursor
  4. Hover mouse over left crosshair and pay attention to the right one.
    • Expected: right one would display crosshair in the same state as it was when cursor has left its area.
    • Actual: In some cases it displays the state of crosshair on the moment when window has stopped resizing.

Can you reproduce this behaviour? Is this a bug or something wrong with the code?

BTW, I'm using Java 8 update 45(x64), OS is Windows 8.

0

There are 0 answers