Arquivo Java Eclipse FileInputStream x fluxo de entrada ao carregar o arquivo de fonte [duplicado]
Esta pergunta já tem uma resposta aqui:
Como acessar um arquivo txt em um jar com FileInputStream? 3 respostasEstou passando por alguns tutoriais e tenho um problema ao carregar o arquivo de fonte no Eclipse Java Project. Tentei muitas soluções sugeridas aqui no SO e, eventualmente, encontrei uma (usando FileInputStream) que funciona para mim, mas não quando o projeto é exportado como JAR executável. Por outro lado, usando a mesma estrutura de diretórios do outro projeto em que carrego ícones, acho que o problema não está no próprio caminho.
Aqui está a estrutura de diretórios:
Aqui está o código:
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();
}
}
Então, o que me incomoda é:
- Por que isso não está funcionando (parece que não é possível encontrar o arquivo de fonte), pois lança NullPointerException
fis = this.getClass().getResourceAsStream("/examples/resources/vedrana.ttf");
nem isso está funcionando
fis = this.getClass().getClassLoader().getResourceAsStream("/examples/resources/verdana.ttf");
- Por que isso funciona no projeto Eclipse, mas não quando exportado para o JAR executável
fis = new FileInputStream(new File(getClass().getResource("/examples/resources/verdana.ttf").toURI()));
ATUALIZAR Como se viu, isso funcionará:
fis = this.getClass().getClassLoader().getResourceAsStream("examples/resources/verdana.ttf");
O problema estava na primeira barra - o caminho deveria ser "examples / resources / verdana.ttf" em vez de "/examples/resources/verdana.ttf". Ele funciona no Eclipse e no JAR executável.
Agora, o que me intriga é por que é que a primeira barra é necessária neste caso
ImageIcon loadIcon = new ImageIcon(getClass().getResource("/examples/resources/load.gif"));
ATUALIZAÇÃO 2: Depois de ficar frustrado por que esse método não funciona
InputStream fis = this.getClass().getResourceAsStream("/examples/resources/verdana.ttf");
Excluí toda a classe do Eclipse e agora os dois métodos funcionam no Eclipse e executam o JAR - exatamente como deveria ser.
InputStream fis = this.getClass().getResourceAsStream("/examples/resources/verdana.ttf");
ou
InputStream fis = this.getClass().getClassLoader().getResourceAsStream("examples/resources/verdana.ttf");