简体   繁体   English

JPanel paint()有时不绘制图像

[英]JPanel paint() not drawing image at times

I'm trying to draw a graphical depiction of the moon. 我正在尝试绘制月球的图形描绘。 For this I am first painting a JPanel black and then painting an Image to depict the moon on it. 为此,我首先绘制一个JPanel黑色,然后绘制一个Image来描绘它上面的月亮。 All fine till here. 一直都好到这里。

Next a second Image (a mask) is painted on top to simulate the Earth's shadow to get the different phases. 接下来,在顶部绘制第二个Image (一个蒙版)以模拟地球的阴影以获得不同的阶段。 However, at times the mask is painted but at times it is not painted, leading to a full moon being shown incorrectly. 但是,有时面具会被涂上,但有时它不会被涂上,导致满月显示不正确。 This is happening totally at random! 这完全是随机发生的! While left clicking , I'm getting this for mask-01.png , mask-06.png , mask-12.png , mask-17.png . left clicking ,我得到的是mask-01.pngmask-06.pngmask-12.pngmask-17.png

A GIF with the individual frames after each Right click : https://drive.google.com/file/d/0B0lWxG68xR4mTlFYYU81N1kzaVE/view?usp=sharing 每次Right click后都有一个带有各个框架的GIF: https//drive.google.com/file/d/0B0lWxG68xR4mTlFYYU81N1kzaVE/view?usp=sharing

What am I doing wrong? 我究竟做错了什么?

The code: 编码:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class App {
    int moonAgeDays = 0;
    float LUNAR_CYCLE_DAYS = 29.5306f;
    JFrame frame;
    MoonImage moonImage;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    App window = new App();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    App() {
        frame = new JFrame("Moon Draw");
        frame.setLocationByPlatform(true);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        moonImage = new MoonImage();
        moonImage.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent mouseEvent) {
                moonAgeDays += mouseEvent.getButton() == MouseEvent.BUTTON1 ? 1 : -1;
                if (moonAgeDays < 0)
                    moonAgeDays = (int) LUNAR_CYCLE_DAYS;
                else if (moonAgeDays > LUNAR_CYCLE_DAYS)
                    moonAgeDays = 0;
                updateMask();
            }
        });
        frame.getContentPane().add(moonImage);

        updateMask();
        frame.pack();
    }

    void updateMask() {
        int phase = (int) Math.toDegrees(Math.acos(-Math.cos(moonAgeDays
                / LUNAR_CYCLE_DAYS * 2 * Math.PI)));
        moonImage.update(phase, moonAgeDays > LUNAR_CYCLE_DAYS / 2 ? 180 : 0);
    }
}

class MoonImage extends JPanel {
    private int phaseAngle = 0;
    private int rotateBy = 0;
    private static final long serialVersionUID = 1L;
    private final int MOON_PADDING = 10;
    private final int MOON_SIZE = 130;
    private final Image IMAGE_MOON = Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/moon.png"));
    private final Image IMAGE_MASK[] = {Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-01.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-02.png"))  ,
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-03.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-04.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-05.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-06.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-07.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-08.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-09.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-10.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-11.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-12.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-13.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-14.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-15.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-16.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-17.png")),
            Toolkit.getDefaultToolkit().createImage(MoonImage.class.getResource("/resources/mask-18.png"))};

    MoonImage() {
        this.setPreferredSize(new Dimension(MOON_SIZE + MOON_PADDING * 2, MOON_SIZE + MOON_PADDING * 2));
    }

    /** Update MoonImage with a Mask and Angle to rotate Mask by*/
    public void update(int phaseAngle, int rotateBy) {
        this.phaseAngle = phaseAngle;
        this.rotateBy = rotateBy;
        repaint();
    }

    @Override
    public void paintComponent(Graphics graphic) {
        super.paintComponent(graphic);

        boolean resultMaskDraw = false;

        Graphics2D graphics2d = (Graphics2D) graphic;
        graphics2d.setColor(Color.BLACK);
        graphics2d.fillRect(0, 0, MOON_SIZE + MOON_PADDING * 2, MOON_SIZE + MOON_PADDING * 2);
        graphics2d.drawImage(IMAGE_MOON, MOON_PADDING, MOON_PADDING, this);
        int phaseBy10 = Math.round(phaseAngle / 10);
        if (phaseBy10 != 0) {
            if (rotateBy != 0) {
                AffineTransform at = new AffineTransform();
                at.translate(MOON_SIZE / 2 + MOON_PADDING, MOON_SIZE / 2 + MOON_PADDING);
                at.rotate(Math.toRadians(rotateBy));
                at.translate(-MOON_SIZE / 2, -MOON_SIZE / 2);
                resultMaskDraw = graphics2d.drawImage(IMAGE_MASK[phaseBy10 - 1], at, this);

            } else
                resultMaskDraw = graphics2d.drawImage(IMAGE_MASK[phaseBy10 - 1], MOON_PADDING, MOON_PADDING, this);
        }
        String maskInfo = phaseBy10 == 0 ? "No mask" : String.format("mask-%02d.png", phaseBy10);
        graphics2d.setColor(phaseBy10 == 0 || resultMaskDraw ? Color.BLUE : Color.RED);
        graphics2d.drawString((phaseBy10 == 0 || resultMaskDraw ? "Drew: " : "Failed: ")
                + maskInfo, 5, MOON_SIZE + MOON_PADDING * 2 - 5);
    }
}

I have tried this in Linux (Kubuntu with OpenJDK) and Windows 7. Same issue in both... 我在Linux(Kubuntu with OpenJDK)和Windows 7中尝试了这个。两者都有同样的问题...

Note : 注意

  1. System has decent specs, 8GiB of RAM and a 500GiB SSD with enough free space. 系统具有不错的规格,8GiB的RAM和500GiB SSD,有足够的可用空间。
  2. What is even more surprising is that there is failure in drawImage() for almost all the images; 更令人惊讶的是,几乎所有图像都存在drawImage()失败; you'll see the info text painted in red first then in blue! 你会看到信息文字首先涂成红色,然后是蓝色!

Figured it! 算了吧!

On line 118 it should be: 在第118行它应该是:

resultMaskDraw = graphics2d.drawImage(IMAGE_MASK[phaseBy10 - 1], at, this);

instead of 代替

resultMaskDraw = graphics2d.drawImage(IMAGE_MASK[phaseBy10 - 1], at, null);

But really strange as the draw fails only at some times and not always! 但真的很奇怪,因为平局只在某些时候失败而且并非总是如此!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM