加载图标资源错误

在Eclipse中,当我运行代码时,这有效:

import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; public class Main { public static void main(String[] args) { JFrame frame = new JFrame("test viewing images"); frame.setSize(600,300); frame.setLocationRelativeTo(null); // centered on monitor frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); /** * Menu Bar stuff */ JMenuBar menuBar; JMenu menu; JMenuItem menuItem; // MENU BAR menuBar = new JMenuBar(); frame.setJMenuBar(menuBar); menuBar.setVisible(true); // MENU 1 menu = new JMenu("File"); menuBar.add(menu); // MENU 1 ITEM ImageIcon icon = new ImageIcon("src/Action-exit-icon.png"); menuItem = new JMenuItem("Exit Program", icon); menu.add(menuItem); frame.setVisible(true); } } 

这是我的Package Explorer中的文件结构:

 ShowImage (project) > src / Main.java > src / Action-exit-icon.png 

此外,此工作空间位于Z:\ eclipse_projects中

我可以看到ImageIcon icon = new ImageIcon(“src / Action-exit-icon.png”); 工作很好,menuBar做的工作。

现在让我们导出这个项目,我将把JAR发送给我的一个朋友。

  1. 右键单击项目>选择导出
  2. 选择Java> Runnable JAR File
  3. 我在启动配置中选择主文件
  4. 导出目的地:我的桌面
  5. 库处理:将所需的库提取到生成的JAR中
  6. 转到我的桌面,双击ShowImage.jar

JFrame显示,但Action-exit-icon.png根本没有出现。

当我打开ShowImage.jar,查看它的内容时,我看到Main.class,Action-exit-icon.png,META-INF。

好吧,我对如何引用图像或任何资源感到非常困惑。 我究竟做错了什么?

 new ImageIcon("src/Action-exit-icon.png"); 

ImageIconString构造函数假定该字符串表示File路径。

该图像显然是一个应用程序资源,并且在部署时(在Jar中)将成为嵌入式资源。 因此,必须通过URL从应用程序的运行时类路径访问它,如下所示:

 new ImageIcon(getClass().getResource("/src/Action-exit-icon.png")); 

检修代码,我明白了:

 import java.awt.Color; import javax.swing.*; public class JavaGui148 { public JComponent getGUI() { JPanel p = new JPanel(); p.setBackground(Color.GREEN); return p; } public JMenuBar getMenuBar() { /** * Menu Bar stuff */ JMenuBar menuBar; JMenu menu; JMenuItem menuItem; // MENU BAR menuBar = new JMenuBar(); menuBar.setVisible(true); // MENU 1 menu = new JMenu("File"); menuBar.add(menu); // MENU 1 ITEM ImageIcon icon = new ImageIcon(getClass().getResource( "/src/Action-exit-icon.png")); menuItem = new JMenuItem("Exit Program", icon); menu.add(menuItem); return menuBar; } public static void main(String[] args) { Runnable r = new Runnable() { @Override public void run() { JavaGui148 gui = new JavaGui148(); JFrame f = new JFrame("Demo"); f.setJMenuBar(gui.getMenuBar()); f.add(gui.getGUI()); // Ensures JVM closes after frame(s) closed and // all non-daemon threads are finished f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); // See http://stackoverflow.com/a/7143398/418556 for demo. f.setLocationByPlatform(true); // ensures the frame is the minimum size it needs to be // in order display the components within it f.pack(); // should be done last, to avoid flickering, moving, // resizing artifacts. f.setVisible(true); } }; // Swing GUIs should be created and updated on the EDT // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html SwingUtilities.invokeLater(r); } }