Ошибка загрузки ресурса Icon
В 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);
}
}
А вот структура файла из моего проводника пакетов:
ShowImage (project)
> src / Main.java
> src / Action-exit-icon.png
Также это рабочее пространство находится в Z:\eclipse_projects
Я вижу значок ImageIcon = новый ImageIcon("src/Action-exit-icon.png"); работает хорошо, и menuBar делает свою работу.
Теперь давайте экспортируем этот проект, и я отправлю JAR по электронной почте моему другу.
- Щелкните правой кнопкой мыши проект> Выбрать Экспорт
- Выберите "Java"> "Запускаемый файл JAR".
- Я выбираю основной файл в конфигурации запуска
- Место назначения экспорта: мой рабочий стол
- Обработка библиотек: Извлечение необходимых библиотек в сгенерированный JAR
- перейти на мой рабочий стол, дважды щелкните ShowImage.jar
Появляется JFrame, но Action-exit-icon.png вообще не появляется.
Когда я открываю ShowImage.jar, чтобы просмотреть его содержимое, я вижу Main.class, Action-exit-icon.png, META-INF.
Хорошо, я серьезно озадачен тем, как ссылаться на изображение или любой ресурс сейчас. Что я делаю неправильно?
1 ответ
new ImageIcon("src/Action-exit-icon.png");
String
конструктор для ImageIcon
предполагает, что строка представляет 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://stackru.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);
}
}