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中迭代数组。并重新绘制卵形。下面是一个类似的答案,这将有所帮助,但它会绘制矩形: