【问题标题】: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。当我点击UserPanelBufferedImage 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 这是固定代码。我希望你知道这不是家庭作业和作业。

标签: java image swing awt


【解决方案1】:

终于有答案了。我更改了 HashMap 对象。我将 HashMap 用于放置图像类。但现在我将 BufferedImage 存储在 HashMap 中。它运作良好。当我第一次点击时,它立即绘制了一个红星。然后我读到了 Image 和 BufferedImage 之间的区别。但我不知道为什么 Image 不能很好地工作,而 BufferedImage 工作得很好。(你能解释一下吗?请)

private HashMap&lt;String, Image&gt; qwirkleImages;

改为

private HashMap&lt;String, BufferedImage&gt; 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) {
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-08
    • 1970-01-01
    • 1970-01-01
    • 2015-06-05
    相关资源
    最近更新 更多