某些图像无法立即绘制
Posted
技术标签:
【中文标题】某些图像无法立即绘制【英文标题】:Some Image couldn't draw immediately 【发布时间】:2017-01-31 18:52:41 【问题描述】:我是 Java GUI 编程的新手。以下代码是我简化的问题。
单击面板时会绘制两个图像。一个是使用drawVrImage()
方法绘制的Red Box,另一个是使用drawRealImage()
方法绘制的Red Star。所有图像中的两个是沿着增加的行绘制的。
这是结果图片:
点击5次后显示。但问题是drawRealImage()
仅绘制了 4 次图像,即使它被调用了 5 次。第一个红盒子在哪里?为什么BufferedImage
不能显示第一个红框。
GUI
类仅用于加载图像。所有图像都已加载并在启动时放置HashMap
。所以,我认为图像加载(Qwirkle.getImage()
)没有问题。我认为缓冲图像没有 Image Observer 是问题。但是如果真的有问题。如何画第二个红框。
供您参考。这里是代码解释。 BIsource
类有一个 BuffedImage
。当我点击UserPanel
。 BufferedImage
in BIsource
获取其图形并绘制图像。完成绘制图像后,UserPanel
从 BIsource 获取该图像。并调用reapint()
方法。 UserPanel
中的 paintCompent()
方法仅适用于从 BIsource Instance 绘制缓冲图像。
我该如何解决这个问题?
用户面板类
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class UserPanel extends JPanel implements MouseListener
private BIsource draw;
private BufferedImage bi;
public UserPanel()
this.draw = new BIsource();
this.bi = draw.getBI();
this.addMouseListener(this);
@Override
protected void paintComponent(Graphics g)
// TODO Auto-generated method stub
g.drawImage(bi, 0, 0, this);
@Override
public void mouseClicked(MouseEvent e)
this.draw.drawVrImage();
this.draw.drawRealImage();
this.draw.incIndex();
bi = this.draw.getBI();
this.repaint();
class BIsource
private BufferedImage biCanvas;
private HashMap<String, BufferedImage> imageMap;
private int index = 0;
public BIsource()
// biCanvas Declaration
biCanvas = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = biCanvas.createGraphics();
g.setColor(Color.blue);
g.fillRect(0, 0, 500, 500);
g.dispose();
imageMap = new HashMap<>();
this.createVrImage();
private void createVrImage()
BufferedImage vrImage = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = vrImage.createGraphics();
g.setColor(Color.red);
g.fillRect(0, 0, 50, 48);
g.dispose();
this.imageMap.put("TEST IMAGE", vrImage);
public BufferedImage getBI()
return this.biCanvas;
public void drawVrImage()
Graphics g = biCanvas.createGraphics();
g.drawImage(this.imageMap.get("TEST IMAGE"), 0, index * 50, null);
g.dispose();
public void drawRealImage()
Graphics g = biCanvas.getGraphics();
g.drawImage(Qwirkle.getImage("RED STAR"), 200, index * 50, null);
g.dispose();
public void incIndex()
index += 1;
public static void main(String[] args)
Qwirkle.loadQwirkleImage();
JFrame mainFrame = new JFrame("Test Frame");
mainFrame.setLayout(null);
mainFrame.setSize(500, 500);
mainFrame.setVisible(true);
mainFrame.setBackground(Color.black);
mainFrame.setLocation(800, 400);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
UserPanel userPanel = new UserPanel();
mainFrame.add(userPanel);
userPanel.setSize(500, 500);
userPanel.setVisible(true);
@Override
public void mouseEntered(MouseEvent e)
@Override
public void mouseExited(MouseEvent e)
@Override
public void mousePressed(MouseEvent e)
@Override
public void mouseReleased(MouseEvent e)
Qwirkle 类
import java.awt.Image;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Random;
public class Qwirkle implements Serializable
private static HashMap<String, Image> qwirkleImages;
// static initialize
static
public enum Color
CYAN, GREEN, ORANGE, PURPLE, RED, YELLOW
public enum Shape
CIRCLE, CLOVER, DIAMOND, RECTANGLE, STAR, URCHIN
private final Color color;
private final Shape shape;
private final int index;
public Qwirkle(Color color, Shape shape, int index)
this.color = color;
this.shape = shape;
this.index = index;
public static void loadQwirkleImage()
if (Qwirkle.qwirkleImages == null)
Qwirkle.qwirkleImages = new HashMap<>();
String key;
try
for (Qwirkle.Color color : Qwirkle.Color.values())
for (Qwirkle.Shape shape : Qwirkle.Shape.values())
key = new String(color.toString() + " " + shape.toString());
Qwirkle.qwirkleImages.put(key, GUI.loadImage(key + ".jpg"));
catch (Exception e)
e.printStackTrace();
else
System.err.println("Already Loading all Qwirkle Image");
public static Image getImage(String key)
return qwirkleImages.get(key);
synchronized public String getKey()
return new String(color.toString() + " " + shape.toString());
@Override
public String toString()
return new String(color.toString() + " " + shape.toString() + " " + index);
public Color getColor()
return color;
public Shape getShape()
return shape;
【问题讨论】:
如果调试没有立竿见影的帮助,请创建minimal reproducible example 关注问题所在。在您的示例中,通过URL
访问发布的图像,如here 所示;使用合成图像,如图here;或者使用UIManager
图标,如图here。
您的程序没有 qwirkle 并且只有另一个图像可以正常工作 - 我建议您不要使用静态;删除所有静态(并同步,除非你真的知道你需要它(不仅仅是为了好玩)
@gpasch 这是固定代码。我希望你知道这不是家庭作业和作业。
【参考方案1】:
终于有答案了。我更改了 HashMap 对象。我将 HashMap 用于放置图像类。但现在我将 BufferedImage 存储在 HashMap 中。它运作良好。当我第一次点击时,它立即绘制了一个红星。然后我读到了 Image 和 BufferedImage 之间的区别。但我不知道为什么 Image 不能很好地工作,而 BufferedImage 工作得很好。(你能解释一下吗?请)
private HashMap<String, Image> qwirkleImages;
改为
private HashMap<String, BufferedImage> qwirkleImages;
这里是固定代码。这是result image
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.util.HashMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class UserPanel extends JPanel implements MouseListener
private BIsource draw;
private BufferedImage bi;
public UserPanel()
this.draw = new BIsource();
this.bi = draw.getBI();
this.addMouseListener(this);
@Override
protected void paintComponent(Graphics g)
// TODO Auto-generated method stub
g.drawImage(bi, 0, 0, this);
@Override
public void mouseClicked(MouseEvent e)
this.draw.drawVrImage();
this.draw.drawRealImage();
this.draw.incIndex();
bi = this.draw.getBI();
this.repaint();
class BIsource
private BufferedImage biCanvas;
// private HashMap<String, Image> qwirkleImages;
private HashMap<String, BufferedImage> qwirkleImages;
private HashMap<String, BufferedImage> imageMap;
private int index = 0;
public BIsource()
this.qwirkleImages = new HashMap<>();
this.loadAllImage();
// biCanvas Declaration
biCanvas = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = biCanvas.createGraphics();
g.setColor(Color.blue);
g.fillRect(0, 0, 500, 500);
g.dispose();
imageMap = new HashMap<>();
this.createVrImage();
public void loadAllImage()
String key;
try
for (Qwirkle.Color color : Qwirkle.Color.values())
for (Qwirkle.Shape shape : Qwirkle.Shape.values())
key = new String(color.toString() + " " + shape.toString());
qwirkleImages.put(key, GUI.loadImage2(key + ".jpg"));
System.out.println(key);
catch (Exception e)
e.printStackTrace();
private void createVrImage()
BufferedImage vrImage = new BufferedImage(50, 50, BufferedImage.TYPE_INT_ARGB_PRE);
Graphics g = vrImage.createGraphics();
g.setColor(Color.red);
g.fillRect(0, 0, 50, 48);
g.dispose();
this.imageMap.put("TEST IMAGE", vrImage);
public BufferedImage getBI()
return this.biCanvas;
public void drawVrImage()
Graphics g = biCanvas.createGraphics();
g.drawImage(this.imageMap.get("TEST IMAGE"), 0, index * 50, null);
g.dispose();
public void drawRealImage()
Graphics g = biCanvas.getGraphics();
Image image = this.qwirkleImages.get("RED STAR");
if (image == null)
System.out.println("image is null");
g.drawImage(image, 200, index * 50, null);
System.out.println("DRAW Real");
g.dispose();
public void incIndex()
index += 1;
public static void main(String[] args)
System.out.println("load all images");
JFrame mainFrame = new JFrame("Test Frame");
mainFrame.setLayout(null);
mainFrame.setSize(500, 500);
mainFrame.setVisible(true);
mainFrame.setBackground(Color.black);
mainFrame.setLocation(800, 400);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
UserPanel userPanel = new UserPanel();
mainFrame.add(userPanel);
userPanel.setSize(500, 500);
userPanel.setVisible(true);
@Override
public void mouseEntered(MouseEvent e)
@Override
public void mouseExited(MouseEvent e)
@Override
public void mousePressed(MouseEvent e)
@Override
public void mouseReleased(MouseEvent e)
【讨论】:
以上是关于某些图像无法立即绘制的主要内容,如果未能解决你的问题,请参考以下文章