Eclipse-Java-Datei FileInputStream vs Input Stream beim Laden der Schriftartdatei [duplizieren]

Diese Frage hat hier bereits eine Antwort:

Wie kann ich mit FileInputStream auf eine TXT-Datei in einer JAR zugreifen? 3 Antworten

Ich lerne einige Tutorials kennen und habe ein Problem beim Laden der Schriftartdatei in Eclipse Java Project. Ich habe viele hier vorgeschlagene Lösungen auf SO ausprobiert und schließlich eine gefunden (mit FileInputStream), die für mich funktioniert, aber nicht, wenn das Projekt als ausführbare JAR exportiert wird. Auf der anderen Seite funktioniert die gleiche Verzeichnisstruktur in dem anderen Projekt, in das ich Symbole lade. Ich schätze, das Problem liegt nicht im Pfad.

Hier ist die Verzeichnisstruktur:

Hier ist der Code:

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();
    }
}

Also, was mich stört, ist:

- Warum dies nicht funktioniert (es scheint, dass die Schriftartdatei nicht gefunden werden kann), da es eine NullPointerException auslöst

fis = this.getClass().getResourceAsStream("/examples/resources/vedrana.ttf");

das funktioniert auch nicht

fis = this.getClass().getClassLoader().getResourceAsStream("/examples/resources/verdana.ttf");

- Warum dies innerhalb des Eclipse-Projekts funktioniert, aber nicht, wenn es in eine ausführbare JAR exportiert wird

fis = new FileInputStream(new File(getClass().getResource("/examples/resources/verdana.ttf").toURI()));

AKTUALISIEREN Wie sich herausstellte, wird dies funktionieren:

fis = this.getClass().getClassLoader().getResourceAsStream("examples/resources/verdana.ttf");

Das Problem befand sich im ersten Schrägstrich. Der Pfad sollte "examples / resources / verdana.ttf" anstelle von "/examples/resources/verdana.ttf" lauten. Es funktioniert sowohl in Eclipse als auch in lauffähigem JAR.

Was mich jetzt interessiert, ist, warum dann dieser erste Schrägstrich in diesem Fall notwendig ist

ImageIcon loadIcon = new ImageIcon(getClass().getResource("/examples/resources/load.gif"));

UPDATE 2: Nachdem ich frustriert war, warum diese Methode nicht funktioniert

InputStream fis = this.getClass().getResourceAsStream("/examples/resources/verdana.ttf");

Ich habe die ganze Klasse aus Eclipse gelöscht und jetzt funktionieren BEIDE Methoden in Eclipse und Runanble JAR - so wie es sein sollte.

InputStream fis = this.getClass().getResourceAsStream("/examples/resources/verdana.ttf");

oder

InputStream fis = this.getClass().getClassLoader().getResourceAsStream("examples/resources/verdana.ttf");

Antworten auf die Frage(2)

Ihre Antwort auf die Frage