Регистрация шрифтов из бросков classpath java.nio.BufferUnderflowException - PullRequest
0 голосов
/ 26 мая 2018

По сути, я пытаюсь зарегистрировать все шрифты (.ttf) в каталоге в classpath.Делать это во время работы в виде jar-файла сложнее, чем когда приложение запускается из IDE.Когда я запускаю приложение из своей среды IDE, не возникает никаких исключений, и я могу сразу использовать шрифты.Однако, когда я запускаю приложение через файл jar, оно по-прежнему регистрирует шрифт, но выдает это исключение:

java.awt.FontFormatException: java.nio.BufferUnderflowException
at sun.font.TrueTypeFont.init(Unknown Source)
at sun.font.TrueTypeFont.<init>(Unknown Source)
at sun.font.TrueTypeFont.<init>(Unknown Source)
at sun.font.SunFontManager.createFont2D(Unknown Source)
at java.awt.Font.<init>(Unknown Source)
at java.awt.Font.createFont0(Unknown Source)
at java.awt.Font.createFont(Unknown Source)
at com.cyr1en.cgdl.util.FontUtil.lambda$registerAllFonts$1(FontUtil.java:65)
at java.util.ArrayList.forEach(Unknown Source)
at com.cyr1en.cgdl.util.FontUtil.registerAllFonts(FontUtil.java:63)
at com.cyr1en.test.Launcher.main(Launcher.java:20)

Но, как я уже сказал, шрифты все еще зарегистрированы, и я все еще смог его использовать.

Вот моя функция регистрации:

public static void registerAllFonts(String fontsDir) {
    try {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        final File jarFile = new File(FontUtil.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
        if (FileUtil.isJarFile(jarFile)) {
            JarFile jar = new JarFile(jarFile);
            Enumeration<JarEntry> entries = jar.entries();
            ArrayList<JarEntry> jarEntries = Collections.list(entries);
            List<JarEntry> fonts = jarEntries.stream().filter(f -> f.getName().startsWith(fontsDir)).collect(Collectors.toList());
            fonts.forEach(f -> {
                try {
                    ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, jar.getInputStream(f)));
                } catch (FontFormatException | IOException e) {
                    ExceptionUtil.generateErrorLog(e);
                }
            });
            jar.close();
        } else {
            URL url = FontUtil.class.getResource(fontsDir);
            if (url != null) {
                File file = new File(url.toURI());
                if (file.listFiles() != null)
                    for (File f : file.listFiles()) {
                        ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, f));
                    }
            }
        }
    } catch (IOException | FontFormatException | URISyntaxException e) {
        ExceptionUtil.generateErrorLog(e);
    }
}

1 Ответ

0 голосов
/ 26 мая 2018

Мой предикат в filter () включает в себя сам каталог шрифтов.Таким образом, в списке я получаю [fonts/, fonts/font1.ttf, fonts/font2.ttf], и, конечно, вы не можете создать шрифт из fonts/.

. Поэтому решение состоит в том, чтобы отредактировать предикатдо:

.filter(f -> f.getName().startsWith(finalFontsDir) && !f.getName().equals(finalFontsDir))

Благодаря @ Робин Грин

Редактировать:

Также немного изменил функцию с момента передачи"fonts/", поскольку каталог на самом деле не будет работать для class.getResource(fontsDir) и будет работать только для JarEntry#getName().Так что просто передайте "/fonts/" и при запуске с jar просто удалите первый /.

 public static void registerAllFonts(String fontsDir) {
    try {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        final File jarFile = new File(FontUtil.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
        if (FileUtil.isJarFile(jarFile)) {
            if(fontsDir.startsWith("/"))
                fontsDir = fontsDir.substring(1);
            JarFile jar = new JarFile(jarFile);
            Enumeration<JarEntry> entries = jar.entries();
            ArrayList<JarEntry> jarEntries = Collections.list(entries);
            final String finalFontsDir = fontsDir;
            List<JarEntry> fonts = jarEntries.stream()
                    .filter(f -> f.getName().startsWith(finalFontsDir) && 
                            !f.getName().equals(finalFontsDir))
                    .collect(Collectors.toList());
            fonts.forEach(f -> {
                try {
                    ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, jar.getInputStream(f)));
                } catch (FontFormatException | IOException e) {
                    e.printStackTrace();
                }
            });
            jar.close();
        } else {
            URL url = FontUtil.class.getResource(fontsDir);
            if (url != null) {
                File file = new File(url.toURI());
                if (file.listFiles() != null)
                    for (File f : file.listFiles()) {
                        ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, f));
                    }
            }
        }
    } catch (IOException | FontFormatException | URISyntaxException e) {
        ExceptionUtil.generateErrorLog(e);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...