【问题标题】:JWindow won't display ImageIconJWindow 不会显示 ImageIcon
【发布时间】:2015-10-08 10:12:24
【问题描述】:

我想知道为什么我的 JWindow 不会显示我的图像。我有这个代码:

JWindow window = new JWindow();
JPanel jp = new JPanel();
JLabel l = new JLabel(new ImageIcon("GenericApp.png"));
jp.add(l);
window.add(jp);
window.setBounds(500, 150, 300, 200);
window.setVisible(true);
try {
    Thread.sleep(5000);
} catch (InterruptedException e) {
    e.printStackTrace();
}
window.setVisible(false);

编辑:我的代码现在是(回到原来的):

final JWindow window = new JWindow();
JPanel jp = new JPanel();
JLabel l = new JLabel(new ImageIcon(Asset.class.getResource("GenericApp.png")));
jp.add(l);
window.add(jp);
window.setBounds(500, 150, 300, 200);
window.setVisible(true);
try{
    Thread.sleep(5000);
}catch(InterruptedException e){
    e.printStackTrace();
}
window.setVisible(false);

是的,我决定使用Thread.sleep()。我的 jar 从 /Users/thomasokeeffe/Desktop/eclipse/AI/AI 执行,这就是图片所在的位置。启动时我仍然得到一个空白的 JWindow。而System.out.println(new File("GenericApp.png").exists()); 返回 true。

又一次编辑如果我把图片放在jar文件中会更容易吗?最奇怪的事情之一是,当我不在应用程序中运行jar并将图片放在工作目录中时,它仍然显示一个空白矩形.......

编辑 到目前为止,我已经尝试使用 URL,并通过获取 user.dir 系统属性进行调试。我现在有这两行代码来获取图片(图片与类在同一个包中):

URL url = this.getClass().getResource("GenericApp.png");
JLabel l = new JLabel(new ImageIcon(url));

我也尝试过使用 InputStream:

InputStream is = this.getClass().getResourceAsStream("GenericApp.png");
Image image = null;
try {
    image = ImageIO.read(is);
} catch (IOException e1) {
    // TODO Auto-generated catch block
    e1.printStackTrace();
}

我做错了什么?

【问题讨论】:

  • Thread.sleep(5000); 可能不会有帮助。有关详细信息,请参阅 Concurrency in SwingHow to use Swing Timers。窗口真的出现了吗?
  • 我不知道将代码放在哪里,在计时器之前、之后还是在计时器中。
  • 部分代码位于Timer,尤其是setVisible(false)。图像存储在哪里(在项目源的上下文中)?
  • 我的 jar 在应用程序中。图片在带有 jar 的 java 文件夹中
  • 假设图像与 Jar 位于同一目录中并且程序从与 Jar 相同的位置执行,那么您的图像应该加载。尝试改用JLabel(new ImageIcon(ImageIO.read(new File("GenericApp.png")))),如果无法读取图像,则会抛出IOException

标签: java swing embedded-resource imageicon


【解决方案1】:

如果图像在您的 jar 中或通常在您的类路径中,您可以通过

getClass().getResource(resourcePath);

资源路径植根于类路径的根目录。

例如,与您的班级在同一目录中的图像将是

new JLabel(new ImageIcon(getClass().getResource("GenericApp.png")));

【讨论】:

  • “我的 jar 在应用程序中。图片在带有 jar 的 java 文件夹中” - 所以,基于此,我会说,不,不是在罐子里……
  • 此方法的一个优点是,当找不到图像时,您将获得 NPE,这与您现在使用的方法不同,它会静默失败。
  • ImageIO.read 也会抛出一个IOExceptionImageIcon 更好,但是如果Jar 文件中不存在该资源,它不会解决问题...
  • @MadProgrammer 很难解释海报的确切含义。真正重要的是图像位于相对于类路径根的某个位置。对于一个独立的应用程序,情况几乎总是如此。许多构建系统会为此专门生成一个资源目录。
  • 如果不是呢?就像执行上下文与 Jar 的源位置不同?解决不了问题
【解决方案2】:

GUI 代码适用于事件调用。当您的函数在主线程中执行时,屏幕上不会发生任何变化。屏幕上的实际更改是在对代码的调用之间完成的。这意味着您的功能应该尽快完成。

所以要得到一些东西来显示你需要返回。

要将一些代码排队等待稍后执行,您可以使用 javax.swing.Timer:

JWindow window = new JWindow();
JPanel jp = new JPanel();
JLabel l = new JLabel(new ImageIcon("GenericApp.png"));
jp.add(l);
window.add(jp);
window.setBounds(500, 150, 300, 200);
window.setVisible(true);
Timer timer = new Timer(5000, new ActionListener(){
    void actionPerformed(ActionEvent e){
        window.setVisible(false);
    }
});
timer.setRepeats(false);//only do this once
timer.start();

【讨论】:

  • 它给出一个错误:删除参数以匹配 Timer()
  • @TheWrenchintheSystem import javax.swing.Timer; 标准库中有另一个计时器类喜欢与摆动计时器冲突。
  • 主程序出现在启动窗口消失之前。
  • 虽然我规定了使用 Swing Timer 的想法,但您假设 OP 已在其上下文中启动程序。在询问是否显示窗口时,OP 回答 “是,但它是空白的”,这表明它们没有在 EDT 中运行。这也不能解决图片不显示的问题
猜你喜欢
  • 1970-01-01
  • 2012-06-08
  • 1970-01-01
  • 2017-01-03
  • 1970-01-01
  • 2015-07-31
  • 2020-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多