[英]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.png
, mask-06.png
, mask-12.png
, mask-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 : 注意 :
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.