我已经尝试了几个小时了。我有一个扩展JComponent的类,在我的paintComponent中我试图绘制一个图像,但我无法做到。这是我的代码:
public class Main extends JComponent{
public static void main(String[] args) {
Main main = new Main();
JFrame frame = new JFrame(Info.getGameTitle());
frame.add(main);
frame.setSize(Info.getWidth(), Info.getHeight());
frame.setResizable(false);
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
System.out.println("Window closed");
System.exit(0);
}
});
frame.setAlwaysOnTop(true);
frame.setFocusable(true);
frame.setAutoRequestFocus(true);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Graphics g = main.getGraphics();
main.paint(g);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
BufferedImage image = null;
try {
image = ImageIO.read(new FileInputStream("images/01.jpg"));
}catch(FileNotFoundException e) {
System.out.println("Could not find file!");
e.printStackTrace();
}catch(IOException e) {
System.out.println("Could not read file!");
e.printStackTrace();
}
g.drawImage(image, 0, 0, this);
}
}
不会抛出任何异常,因此图像似乎已加载。但是,屏幕上没有任何内容。如果我尝试绘制形状或文本,那很好。 我做错了什么?
编辑:现在我提供了一个工作示例。
答案 0 :(得分:1)
Graphics g = main.getGraphics();
main.paint(g);
不,不,不,不,不!无限次!这不是绘画的作用!
请查看Performing Custom Painting和Painting in AWT and Swing,以便更好地了解绘画在Swing中的工作原理。
getGraphics
可以返回null
并且只返回上次使用的上下文来绘制组件,绘制到它的任何内容都将在下一个绘制周期中被删除。
没有充分的理由手动拨打paint
,只是不要这样做。
你应该做更多的事情
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage img = null;
public TestPane() {
try {
img = ImageIO.read(new FileInputStream("..."));
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public Dimension getPreferredSize() {
return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight());
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (img != null) {
g2d.drawImage(img, 0, 0, this);
}
g2d.dispose();
}
}
}
如果您的图像仍未显示,我怀疑图像放错了位置。
new FileInputStream("images/01.jpg")
建议图像位于执行程序的当前目录中,这并不总是与程序所在的位置相同。
您可以使用System.getProperty("user.dir")
来确定当前"工作"目录并将其与您认为程序所在的位置进行比较。您也可以使用File#exists
来测试文件是否存在,但是,如果是这种情况,我原本希望代码抛出IOException
。
更好的长期解决方案是将图像嵌入到应用程序中(通常将其包含在Jar中),这样可以消除上述问题。
在这种情况下,你需要使用......
ImageIO.read(getClass().getResource("/images/01.jpg"));
加载图片
答案 1 :(得分:0)
试试这个
BufferedImage image = null;
try {
image = ImageIO.read(new File(fullpathname+"/01.jpg"));
}catch(Exception e) {
System.out.println("Could not read file!");
e.printStackTrace();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
阅读引发更多例外
IllegalArgumentException - if input is null.
IOException - if an error occurs during reading.
所以抓住更一般的(例外)将覆盖它
答案 2 :(得分:0)
试试这个:
Image image = ImageIO.read(new File(file)); g.drawImage(image,0,0,this);
答案 3 :(得分:0)
请注意,您的JComponent
每秒可能被涂抹数百次,
例如,当它被另一个移动窗口部分遮挡时。
因此,paint
方法的表现很重要,否则你会得到一个“慢慢地”#34; GUI。
因此我建议将耗时的部分(即读取图像文件)与JComponent
分开。
public class ImageComponent extends JComponent {
private BufferedImage image;
public void setImage(final BufferedImage image) {
this.image = image;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null)
g.drawImage(image, 0, 0, this);
}
}
您的代码中的其他位置您读取图像文件并将其设置到组件中:
BufferedImage image = null;
try {
image = ImageIO.read(new File(fullpathname+"/01.jpg"));
}catch(Exception e) {
System.out.println("Could not read file!");
e.printStackTrace();
}
ImageComponent component = new ImageComponent();
component.setImage(image);