Java 自定义swing组件的图像缓冲区?

Java 自定义swing组件的图像缓冲区?,java,image,swing,buffer,Java,Image,Swing,Buffer,我应该自己实现Image作为后缓冲区,还是已经有了激活后缓冲区的组件或选项 我的目标是在窗口移动和隐藏/显示时保留图形 更新 我曾尝试使用JPanel,因此我认为如果它有缓冲区,它应该可以工作,但失败了: final JPanel panel = new JPanel(); panel.addMouseListener(new MouseListener() { @Override public void

我应该自己实现
Image
作为后缓冲区,还是已经有了激活后缓冲区的组件或选项

我的目标是在窗口移动和隐藏/显示时保留图形

更新

我曾尝试使用JPanel,因此我认为如果它有缓冲区,它应该可以工作,但失败了:

final JPanel panel = new JPanel();

            panel.addMouseListener(new MouseListener() {

                @Override
                public void mouseReleased(MouseEvent e) {
                }

                @Override
                public void mousePressed(MouseEvent e) {
                }

                @Override
                public void mouseExited(MouseEvent e) {
                }

                @Override
                public void mouseEntered(MouseEvent e) {
                }

                @Override
                public void mouseClicked(MouseEvent e) {
                    Graphics2D g2d = (Graphics2D) panel.getGraphics();
                    g2d.drawOval(e.getX()-50, e.getY()-50, 100, 100);
                }
            });

            JFrame frame = new JFrame("JPanel Buffer Test");
            frame.add(panel, BorderLayout.CENTER);
            frame.pack();
            frame.setBounds(100,100, 800, 600);
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.setVisible(true);
这里的圆圈是鼠标点击绘制的,但如果窗口调整大小,圆圈将消失。因此,显然不存在缓冲区

若组件有缓冲区,我将能够在其上绘制一些东西,它将在调整大小时保持不变

是否有其他方法可以访问
JPanel
的缓冲区,而不是
getGraphics

更新2

下面是我如何手动创建缓冲区的。我的问题是,它不是已经在图书馆里完成了吗。 示例在调整缓冲区大小时重新采样,这不是强制性的

    private BufferedImage bufferedImage = null;

@Override
protected void paintComponent(Graphics g) {
    if( bufferedImage != null ) {
        g.drawImage(bufferedImage, 0, 0, null);
    }
}

@Override
public void setBounds(int x, int y, int width, int height) {

    if( bufferedImage == null ) {
        bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    }
    else {
        if( bufferedImage.getWidth() != width || bufferedImage.getHeight() != height ) {
            BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

            AffineTransform at = new AffineTransform();
            at.scale((double)width/bufferedImage.getWidth(), (double)height/bufferedImage.getHeight());

            AffineTransformOp scaleOp = 
                   new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);

            bufferedImage = scaleOp.filter(bufferedImage, scaledImage);
        }
    }
    super.setBounds(x, y, width, height);
}


public Graphics2D createImageGraphics() {
    if( bufferedImage != null ) {
        return bufferedImage.createGraphics();
    }
    else {
        return null;
    }
}

您所需要的只是一个
JPanel
,默认情况下它是自动双缓冲的(更多信息,请参阅),您不仅可以覆盖
paintComponent(…)
,在那里进行所有绘制,还可以将
JPanel
添加到类似
JFrame
的容器中

请在此处查看更多信息:

您可能还希望完全控制
JPanel
的重新绘制周期,这可以通过调用
setIgnoreRepaint(true)
来完成

或者,您可能想看看(这将允许您使用一些高级功能,但对于所有密集用途而言,
JPanel
具有覆盖的
paintComponent
和自动双缓冲,并且
setignorerepain(true)
是等效的),这通常是通过
Canvas
实现的,如下所示:

BufferStrategy myStrategy;

while (!done) {
    Graphics g = myStrategy.getDrawGraphics();
    render(g);//draw the frame/graphics
    g.dispose();
    myStrategy.show();
}

对不起,如果
JPanel
如您所说有缓冲区,我应该重写
paintComponent
做什么
paintComponent
在组件每次需要重新绘制时都会被调用,因此这是一种每次都要重新生成视觉信息的情况。@SuzanCioc我所知道的唯一方法是创建一个数组列表,其中保存您绘制的每个椭圆,然后在paintComponent中迭代数组。并重新绘制椭圆。@SuzanCioc我知道的唯一方法是创建一个数组列表,其中包含您绘制的每个椭圆,然后在paintComponent中迭代数组。并重新绘制卵形。下面是一个类似的答案,这将有所帮助,但它会绘制矩形: