【问题标题】:Regarding a JButton and an ImageIcon关于 JButton 和 ImageIcon
【发布时间】:2012-06-08 20:08:08
【问题描述】:

我目前正在看一本关于java的书,我目前正在研究swing图形用户界面组件。在此过程中,我偶然发现了一个代码示例,其中作者以一种非常不寻常的方式在 JButton 上设置图像,如下所示:

Icon bug1 = new ImageIcon( getClass().getResource( "bug1.gif" ) );

为了使上述操作生效,您需要将图像与 .class 文件放在同一文件夹中。有人可以向我解释他为什么要使用这个特定的代码(据我所知,它必须是反射代码,但话又说回来,我对这个不是特别确定),如果有一种方法可以做到同样的事情,没有像他那样复杂?

【问题讨论】:

    标签: java swing jbutton embedded-resource imageicon


    【解决方案1】:

    只有当你不理解它们时,事情才会变得复杂。一旦你理解了上面的代码是做什么的,它就会变得非常简单。

    getClass() 返回当前对象的 Class 对象 (this)。 getResource() 使用上述相对路径调用,在类路径中查找名为 bug1.gif 的文件,并在与被调用的 Class 对象相同的包中。因此,它会在与包含上述代码的类相同的包中查找 bug1.gif。 getResource() 返回一个 URL。 ImageIcon 构造函数将 URL 作为参数,从该 URL 加载图像字节,并从这些字节构造一个 ImageIcon。

    所以整个事情只是从类路径中可用的文件创建一个 ImageIcon,与调用此代码的类在同一个包中。这是有道理的:您将给定类使用的图像与该类放在同一个包中,然后发布一个包含类和应用程序图像的 jar。

    通过阅读所有这些方法的 javadoc,您会自己弄清楚这一切。

    【讨论】:

    • 你好,谢谢你的回答,我已经明白了上面的代码做了什么,好吧,至少在某种意义上,但我希望有人比我更擅长向我解释,让我看看我是否从一开始就做对了。再次感谢您的澄清回答。
    • 我意识到我还没有真正回答你的疑惑和奇思妙想:没有更简单或更简单的方法可以做到这一点(但我不明白它怎么可能更简单),而且根本不是一种不寻常的方式:这是典型的做法。
    【解决方案2】:

    Java 的 Swing 可以很快克服复杂性,我认为他实际上是为了简单起见而使用此代码。

    如果图像路径是相对路径(示例中的路径是),则图像必须位于与程序的已编译字节码(.class 文件)相同的位置。如果图像在其他任何地方,您的程序根本找不到它。

    像这样的相对路径非常有用,尤其是当您想将完成的项目编译成 JAR 文件时。您的图像将与您的所有 .CLASS 文件一起包含在 JAR 中。您将能够下载并运行您的编译程序,并且您的图像将如您所愿地出现在您的 GUI 中。

    【讨论】:

      【解决方案3】:

      Class#getResource(String) 从类路径返回一个指向资源的 URL。这是加载存储在应用程序 JAR 文件中的资源的一种便捷方式。如果图像位于 HDD 上的某个位置,您可以使用以下命令加载它:

      new ImageIcon(new File("/path/to/the/image").toURI().toURL());
      

      创建 File 对象,并将其路径作为 URL(看起来像 file:///path/to/the/image)。

      或者更简单,因为ImageIcon 有一个构造函数,它接受一个文件名:

      new ImageIcon("/path/to/the/image");
      

      【讨论】:

      • “JButton 上的图像” 暗示它是嵌入式资源。 File 对象不适合访问 Jar 中的资源。
      • 这就是为什么我专门写了如果图像位于硬盘上的某个地方。从 Java 中的类路径打开文件(资源)过于复杂,对于初学者来说很难理解(我花了一些时间),我只是想通过展示它如何与外部文件一起工作来简化案例 - 在我看来- 更容易理解。
      • 我认为使用toURI().toURL() 是当您的文件名包含需要为URL 转义的字符时。这种情况很少见。或者你能解释一下吗?
      • 我测试了它,ImageIconfile.toURL() 正确加载了文件,即使文件名包含空格。但是,您是对的,这不是一个可以效仿的好榜样。 File#toURL() 也被弃用了。我修复了代码。
      猜你喜欢
      • 2015-07-25
      • 2013-05-14
      • 2013-12-21
      • 2014-11-30
      • 2019-03-12
      • 2012-10-24
      • 2011-02-20
      • 1970-01-01
      • 2016-08-25
      相关资源
      最近更新 更多