我直接从“Java all in one for Dummies"中提取了这段代码……为什么它不起作用?

2022-01-24 00:00:00 java eclipse swing imageicon jframe
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;


@SuppressWarnings("serial")
public class Picture extends JFrame{

    public static void main(String[] args){

        new Picture();

    }

    public Picture(){

        this.setTitle("Picture");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel p = new JPanel();
        ImageIcon pic = new ImageIcon("TestImage.jpg");
        p.add(new JLabel(pic));
        this.add(p);
        this.pack();
        this.setVisible(true);
        System.out.println(pic);
    }

}

这个代码只是显示一个折叠的框架.我希望 pack();方法调用会围绕我的 .jpg 图像调整框架的大小,对吗?

This code as it is just displays a collapsed frame. I would expect that the pack(); method call would size the frame around my .jpg image, correct?

我已经可以听到第一个问题,是的,图像与我的项目包文件夹位于同一文件夹中.

I can already hear the first question, and yes the image is in the same folder as my project package folder.

我正在使用 Eclipse IDE.

I am using the Eclipse IDE.

我还添加了 println();语句以查看 Image 引用返回的内容并返回TestImage.jpg".我以为它会返回内存中图像的地址.??

I also added the println(); statement to see what the Image reference returned and it returns "TestImage.jpg". I thought it would return an address of the image in memory.??

我整个上午都在阅读论坛,如果不复制和使用其他人更复杂的代码,我真的找不到任何对我有帮助的东西.我尽量保持简单,以免自己搞糊涂.

I have been reading the forum all morning and I can't really find anything that helps me there without copying and using someone else's more complex code. I am trying to keep this as simple as I can so that I don't confuse myself.

提前感谢您的帮助.

推荐答案

图片与我的项目包文件夹在同一个文件夹中

the image is in the same folder as my project package folder

就是这样.

正如所写,您的程序在当前工作目录中查找图像,而不是包层次结构.

As written, your program looks for the image in the current working directory, not the package hierarchy.

来自 构造函数的Javadoc采用String,它根据需要从指定的文件名读取图像.但是,当您指定相对路径时,这意味着读取相对于运行应用程序的工作目录.

From the Javadoc for the constructor taking String, it reads the image from the specified filename, as desired. However, when you specify a relative path, that means to read relative to the working directory that the application is running in.

要解决此问题,您有 2 个选项:

To work around this, you have 2 options:

  • 指定相对于IDE运行程序的工作目录的图像文件名.我相信Eclipse在项目根目录中运行应用程序,源包层次结构植根于src.在这种情况下,如果您指定 src/TestImage.jpg,它将起作用.缺点是如果您从不同的目录运行程序,则必须将图像文件一起移动.这对于分发/打包很不方便,因为您不能只删除 JAR 文件并让它运行.

  • Specify the image filename relative to the working directory your IDE runs your program in. I believe Eclipse runs applications in the project root directory, and the source package hierarchy is rooted at src. In this case it'll work if you specify src/TestImage.jpg. The disadvantage is that if you ever run your program from a different directory, you'll have to move the image file along with it. This is inconvenient for distribution/packaging, because you can't just drop the JAR file and have it run.

使用 Java 的资源加载器从包层次结构中加载图像文件.为此,首先使用

Use Java's resource loader to load the image file from the package hierarchy. To do this, first use

getClass().getResource("TestImage.jpg")

获取图像的 URL(相对于包根目录).看到 ImageIcon 有一个构造函数,它接受一个 URL 来读取图像.所以你应该使用

to get a URL for the image (relative to the package root). See that ImageIcon has a constructor that accepts a URL to read the image from. So you should read the image using

new ImageIcon(getClass().getResource("TestImage.jpg"))

相对于包层次结构的优点是程序可以从任何位置运行,并且图像可以与您的应用程序捆绑在一个 JAR 文件中.

The advantage of being relative to he package hierarchy is that the program can be run from any location, and the image can be bundled with your app in a single JAR file.

另外:最好的做法是创建一个包,在其中放置代码和资源(而不是仅仅将它们放在包根目录中).在这种情况下,请改为传递 "com/example/someapp/TestImage.jpg".

Aside: it's best practice to create a package in which you place both code and resources (rather than just placing them in the package root). In that case, pass "com/example/someapp/TestImage.jpg" instead.

相关文章