自定义摆动组件的图像缓冲区?

问题描述:

我是否应该自己实现Image作为后备缓冲区,还是已经有组件或选项来激活后台缓冲区?自定义摆动组件的图像缓冲区?

我的目标是坚持下去的窗口移动和隐藏/显示图纸...

UPDATE

我曾尝试使用的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

下面是我怎么手动缓存。我的问题是,它不是已经在图书馆里完成了。 示例resizes缓冲区调整大小,这是不是强制性的。

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,默认为自动为双缓冲(见here更多),你可以不是简单地覆盖paintComponent(..),做所有的绘图有比添加JPanel到容器如JFrame

看看这里更多:

您可能还需要完全控制你的JPanel的重绘周期,这可以通过调用setIgnoreRepaint(true)来完成。

或者你可能想看看BufferStrategy and BufferCapabilities(这将让你一些先进的功能,而且对所有密集的目的JPanel与被覆盖的paintComponent和自动双缓冲setIgnoreRepaint(true)等价),这通常是用一个Canvas实现像这样:

BufferStrategy myStrategy; 

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

对不起,如果'JPanel'有缓冲区,你应该重写'paintComponent'吗?每次组件需要重绘时调用“paintComponent”,所以这是为了每次都要重新生成视觉信息。 –

+0

@SuzanCioc我知道这样做的唯一方法是通过创建一个数组列表来保存您绘制的每个椭圆,在paintComponent中您将遍历数组。并重新绘制椭圆。 –

+0

@SuzanCioc我知道这样做的唯一方法是通过创建一个数组列表来保存您绘制的每个椭圆,在paintComponent中您将遍历数组。并重新绘制椭圆。这是一个类似的答案,它将帮助,但它绘制矩形:http://stackoverflow.com/a/13359279/1133011 –