如何在 JPanel 上绘制组件?

How to paint a component on a JPanel?

我一直在通过 YouTube 教程学习 Java,当涉及到在框架中承载组件时,事情对我来说有点复杂。这节课对我来说有几个东西,比如 super 关键字,Graphics class 和 paint 方法。我设置了一个框架并将这个 JPanel 添加到该框架。我按照我的理解编写了这个练习,但它不会绘制 ImageIcon 而是打开一个完全空的框架。感谢任何提前提供帮助的人。

public class DragPanel extends JPanel{

ImageIcon image=new ImageIcon("walle.png");
Point imageCorner;
Point prevPt;

DragPanel(){
    imageCorner=new Point(0,0);
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    image.paintIcon(this, g, (int)imageCorner.getX(), (int)imageCorner.getY());
}
}

ImageIcon("walle.png") 正在查找与您执行 java 命令的位置相关的文件。

您可以通过在您的代码中添加 System.getProperty("user.dir") 来检查“工作”目录是什么。您还可以使用 System.getProperty(new File("walle.png").exists())

检查当前上下文中是否存在该文件

if that was the case it would cause a FileNotFoundException instead of printing null

实际上,ImageIcon 不会抛出异常,它只是默默地失败,这就是为什么我倾向于建议不要使用它。

相反,您应该使用 ImageIO,除了支持更多格式(并且可以扩展)之外,如果无法加载图像,它也会抛出异常 return 直到图像完全加载。

有关详细信息,请参阅 Reading/Loading an Image

Forementioned PNG is in the same directory

与 class 或工作目录相同的目录?一般来说,我建议习惯使用嵌入式资源,因为它解决了“执行上下文”的许多问题

I don't use an IDE

我可能会推荐使用一个,因为它可以帮助解决其中的一些问题,让您专注于学习语言。

因此,我的目录结构类似于...

src/
    images/
        happy.png
    Whosebug/
        Main.java

在此设置中,happy.png 成为“嵌入式”资源,导出时将与 class 文件打包在一起,这意味着该资源始终位于同一位置, 无论执行上下文如何

package Whosebug;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage image;

        public TestPane() throws IOException {
            image = ImageIO.read(getClass().getResource("/images/happy.png"));            
        }

        @Override
        public Dimension getPreferredSize() {
            return image == null ? new Dimension(200, 200) : new Dimension(image.getWidth(), image.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (image == null) {
                return;
            }
            Graphics2D g2d = (Graphics2D) g.create();
            int x = (getWidth() - image.getWidth()) / 2;
            int y = (getHeight() - image.getHeight()) / 2;
            g2d.drawImage(image, x, y, this);
            g2d.dispose();
        }

    }
}