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:
- Run this, see how crosshairs follow the cursor.
- Resize window by dragging right window border
- Hover the mouse over right crosshair, see how it follows the cursor
- 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.