Файл Eclipse Java FileInputStream против входного потока при загрузке файла шрифта [duplicate]
На этот вопрос уже есть ответ здесь:
Как я могу получить доступ к TXT-файлу в банке с FileInputStream? 3 ответаЯ прохожу некоторые уроки и у меня проблема с загрузкой файла шрифта в Eclipse Java Project. Я перепробовал много решений, предложенных здесь, на SO, и в конце концов нашел одно (используя FileInputStream), которое работает для меня, но не тогда, когда проект экспортируется как исполняемый JAR. С другой стороны, работает та же структура каталогов в другом проекте, куда я загружаю иконки, поэтому я думаю, что проблема не в самом пути.
Вот структура каталогов:
Вот код:
package examples;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Test01 extends JPanel {
String text = "Free the bound periodicals";
Font fon;
FileInputStream fis;
// InputStream fis;
@Override
public void paintComponent(Graphics comp) {
Graphics2D comp2D = (Graphics2D) comp;
// This (for another project) works both in Eclipse and in runnable JAR
// ImageIcon loadIcon = new ImageIcon(getClass().getResource("/examples/resources/load.gif"));
// This (quite contrary to many SO suggestions) doesn't work in Eclipse for this project, why?
// fis = this.getClass().getResourceAsStream("/examples/resources/vedrana.ttf");
// This (quite contrary to many SO suggestions) doesn't work in Eclipse for this project, why?
// fis = this.getClass().getClassLoader().getResourceAsStream("/examples/resources/verdana.ttf");
// This works within Eclipse project but not when exported to runnable JAR,
// Moreover many suggest that InputStream should be favored over FileInputStream
try {
fis = new FileInputStream(new File(getClass().getResource("/examples/resources/verdana.ttf").toURI()));
} catch (FileNotFoundException e1) {
JOptionPane.showMessageDialog(this, "FileNotFoundException!");
} catch (URISyntaxException e1) {
JOptionPane.showMessageDialog(this, "URISyntaxException!");
} catch (Exception e1) {
JOptionPane.showMessageDialog(this, "NullPointerException!");
}
try {
fon = Font.createFont(Font.TRUETYPE_FONT, fis);
} catch (FontFormatException e) {
// TODO Auto-generated catch block
System.out.println("Error - FontFormatException " + e.getMessage());
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println("Error - IOException " + e.getMessage());
}
fon = fon.deriveFont(Font.PLAIN, 72);
FontMetrics metrics = getFontMetrics(fon);
comp2D.setFont(fon);
comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
int x = (getSize().width - metrics.stringWidth(text)) / 2;
int y = getSize().height / 2;
comp2D.drawString(text, x, y);
}
public static void main(String[] args) {
JFrame mainFrame = new JFrame("Main Menu");
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(1000, 250);
mainFrame.setVisible(true);
mainFrame.add(new Test01());
// mainFrame.pack();
}
}
Итак, что меня беспокоит:
Почему это не работает (кажется, он не может найти файл шрифта), поскольку он выдает NullPointerException
fis = this.getClass().getResourceAsStream("/examples/resources/vedrana.ttf");
ни это не работает
fis = this.getClass().getClassLoader().getResourceAsStream("/examples/resources/verdana.ttf");
Почему это работает в проекте Eclipse, но не при экспорте в работающий JAR
fis = new FileInputStream(new File(getClass().getResource("/examples/resources/verdana.ttf").toURI()));
ОБНОВИТЬ Как оказалось, это будет работать:
fis = this.getClass().getClassLoader().getResourceAsStream("examples/resources/verdana.ttf");
Проблема была в первом слэше - путь должен быть "examples / resources / verdana.ttf" вместо "/examples/resources/verdana.ttf". Он работает как в Eclipse, так и в работающем JAR.
Теперь, что меня заинтриговало, так это то, почему тогда необходим первый слеш в этом случае
ImageIcon loadIcon = new ImageIcon(getClass().getResource("/examples/resources/load.gif"));
ОБНОВЛЕНИЕ 2: Разочаровавшись, почему этот метод не работает
InputStream fis = this.getClass().getResourceAsStream("/examples/resources/verdana.ttf");
Я удалил весь класс из Eclipse, и теперь ОБА методы работают в Eclipse и исполняемом JAR - так, как и должно быть.
InputStream fis = this.getClass().getResourceAsStream("/examples/resources/verdana.ttf");
или же
InputStream fis = this.getClass().getClassLoader().getResourceAsStream("examples/resources/verdana.ttf");