首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从类路径注册字体将引发java.nio.BufferUnderflowException

从类路径注册字体将引发java.nio.BufferUnderflowException
EN

Stack Overflow用户
提问于 2018-05-26 06:49:13
回答 1查看 789关注 0票数 0

基本上,我要做的是在类路径中的目录中注册所有字体(.ttf)。与从IDE启动应用程序时相比,在作为jar文件运行时执行此操作要复杂得多。当我从IDE启动应用程序时,不会抛出任何异常,我可以立即使用字体。但是,当我通过jar文件启动应用程序时,它仍然注册字体,但它抛出了这个异常:

代码语言:javascript
复制
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)

但正如我所说,字体仍然注册,我仍然能够使用它。

这是我的注册功能:

代码语言:javascript
复制
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);
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-26 08:01:37

我在filter()中的谓词包含实际的字体目录本身。因此,在列表中,我得到了fonts/fonts/font1.ttffonts/font2.ttf,当然您不能从fonts/创建字体。

因此,解决方案是将谓词编辑为:

代码语言:javascript
复制
.filter(f -> f.getName().startsWith(finalFontsDir) && !f.getName().equals(finalFontsDir))

多亏了@Robin Green

编辑:

另外,由于将"fonts/"作为目录传递给class.getResource(fontsDir)而只对JarEntry#getName()起作用,所以函数也做了一些修改。因此,只要通过"/fonts/",当使用jar启动时,只需删除第一个/即可。

代码语言:javascript
复制
 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);
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50540130

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档