如何在 JPanel 上绘制组件?

发布于 2025-01-12 16:25:33 字数 533 浏览 0 评论 0原文

我一直在通过 YouTube 教程学习 Java,当谈到在框架中携带组件时,事情对我来说有点复杂。这节课对我来说有几件事,比如 super 关键字、Graphics 类和 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());
}
}

I have been learning Java from a YouTube tutorial and when it came to carrying components in a frame, things got a bit complicated for me. There are several things in this lesson for me, such as super keyword, Graphics class and paint method. I setup a frame and added this JPanel to that frame. I wrote this practice as much as I understood but it doesn't paint the ImageIcon and opens a completely empty frame instead. Thanks to anyone who can help in advance.

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());
}
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

小帐篷 2025-01-19 16:25:33

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

您可以通过将 System.getProperty("user.dir") 添加到代码中来检查“工作”目录是什么。您还可以使用 System.getProperty(new File("walle.png").exists()) 检查文件是否存在于当前上下文中

如果是这种情况,它将导致 FileNotFoundException 而不是打印 null

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

相反,您应该使用 ImageIO,部分原因是支持更多格式(并且可扩展),如果图像无法加载,它也会抛出异常,并且在图像完全加载之前不会返回已加载。

有关更多详细信息,请参阅读取/加载图像

上述PNG在同一目录下

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

我不使用 IDE

但我可能会建议使用一个 IDE,因为它将帮助解决其中一些问题并让您专注于学习该语言。

所以,我的目录结构看起来像......

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

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

在此处输入图像描述

package stackoverflow;

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();
        }

    }
}

ImageIcon("walle.png") is looking for the file relative to the location from which you executed the java command.

You can check what the "working" directory is by adding System.getProperty("user.dir") to your code. You can also check to see if the file exists from within the current context using System.getProperty(new File("walle.png").exists())

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

Actually, ImageIcon doesn't throw an exception, it simply fails silently, which is why I tend to recommend not using it.

Instead, you should be using ImageIO, part from supporting more formats (and been expandable), it will also throw an exception if the image can't be loaded and won't return until the image is fully loaded.

See Reading/Loading an Image for more details

Forementioned PNG is in the same directory

Same directory as the class or the working directory? In general, I recommend getting use to using embedded resources, as it resolves many of the issues with "execution context"

I don't use an IDE

I'd probably recommend making use of one as it will help solve some of these issues and let you focus on learning the language.

So, my directory structure looks something like...

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

In this setup, the happy.png becomes an "embedded" resource, which will get packaged with the class files when it's exported, this means, that the resource is always in the same location, no matter the context of execution

enter image description here

package stackoverflow;

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();
        }

    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文