java - JPanel 使用 mouseMoved 方法闪烁

标签 java swing jpanel paintcomponent mouse-listeners

我有一个简单的 JPanel,用于显示图像。我想要一些功能,可以通过拖动来平移图像。我有这样的东西(注意我编译并正确运行的代码;下面的代码被严重截断,只是为了了解我在做什么):

public class Data2DPanel extends JPanel { 
    public Data2DPanel(Data2D data) {
        // Set image
        this.image = Data2D.data2DToBufferedImage(data);

        // Set mouse listener
        Data2DMouseAdapter data2DMouseAdapter = new Data2DMouseAdapter();
        this.addMouseListener(data2DMouseAdapter);
        this.addMouseMotionListener(data2DMouseAdapter);
    }

    private class Data2DMouseAdapter extends MouseAdapter {
        @Override
        public void mouseDragged(MouseEvent e) {
            if (SwingUtilities.isLeftMouseButton(e)) {
                switch (actionState) {
                    case PAN:
                        xOffset = xOffsetInit + e.getX()-xPosInit;
                        yOffset = yOffsetInit + e.getY()-yPosInit;
                        paintComponent(getGraphics());
                        break;                                
                }
            }
        }
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                            RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);

        // Paint image
        g2.drawImage(image,x,y,width,height,this);
        }
    }
}

问题是有很多闪烁。我检查过 stackoverflow/google ,似乎很多闪烁问题都是因为人们重写了 paint 方法而不是 paintComponent 方法。我还检查了 isDoubleBuffered 并且它返回 true。直觉上,我觉得也许 mouseDragged 方法更新太多,以至于 paintComponent() 无法跟上,但我认为双缓冲仍然应该防止闪烁的发生。我的问题是这种方法是否存在本质上的错误,以及是否有一个标准或优雅的解决方案。

最佳答案

paintComponent(getGraphics()); 应该是 repaint()。复杂的问题。

  1. 您永远不想调用 getGraphics() 来进行自定义绘制。用于绘制的唯一 Graphics 对象应该是 Paint 方法中提供的对象。
  2. 您永远不应该调用paintXxx来尝试“强制”组件的重绘。您应该调用 repaint() 并允许 RepaintManager处理所有更新和绘制周期

关于java - JPanel 使用 mouseMoved 方法闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25751022/

相关文章:

java - 支持 Reset() 或 MarkSupported() 的 SocketInputStream 和 InputStream

java - 获取已安装在 OSGi 运行时中的 bundle 的 InputStream?

java - spring:即时添加 xml 上下文?

java - Swing GUI 生成器 Intellij IDEA

java - 重新添加 JCheckBox 组件后,它们不会显示在 JPanel 上

java - volatile + 不可变持有者对象 = 线程安全?

Java Swing GUI - 如何让一个线程一直处于 sleep 状态并通过点击唤醒?

Java:JScrollPane满了就消失

java - KeyListener 不响应按键输入

java - JTable刷新不显示