【问题标题】:Content from Jar file来自 Jar 文件的内容
【发布时间】:2021-06-04 13:16:32
【问题描述】:

是否可以使用 .jar 文件中的 .ttf 文件创建自定义字体? 我已经创建了一个具有以下结构的 jar 文件

Game.jar
├──Snake  
│  ├── lib  
│  |   └── game_over.ttf  
|  ├── src  
│  |   ├── GameFrame.class  
│  |   ├── GamePanel.class  
│  |   └── SnakeGame.class

我试图通过这样做来获取自定义字体

Font GAMEOVER_FONT;
InputStream is = this.getClass().getClassLoader().getResourceAsStream("Snake/lib/game_over.ttf");

GAMEOVER_FONT = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(200f);   
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, is));
g.setFont(GAMEOVER_FONT);

我做错了什么?是否有可能实现我正在尝试的目标?

【问题讨论】:

  • 安德烈,也许这只是你创建问题时的问题,但是你的jar中的字体名称是game_over.tff 。请注意错字,应该是'ttf'。然后使用@cello 中的代码——基本上,在路径中包含Snake 之前的/,并去掉第二个Font.createFont 方法调用,使用ge.registerFont(GAMEOVER_FONT),它应该可以正常工作,
  • 是的,扩展是正确的问题是一个错字
  • 感谢您的澄清。而且,大提琴的代码不起作用?确实应该如此。请问,如果你运行它有什么问题? nullInputStream?
  • 我检查了 if (is == null) 并且当我运行 jar 时我得到了java.io.IOException: Problem reading font data.
  • 拜托,在你的用例中应该是一样的,但是,你能试试this.getClass().getResourceAsStream()而不是this.getClass().getClassLoader().getResourceAsStream()吗?注意getClassLoader(). 的区别。另外,请将字体放在您的类中,您的 Java 输出目录中,并尝试从那里读取它,以检查字体是否存在实际问题。

标签: java jar java-font


【解决方案1】:

1:使用绝对路径访问字体资源,如下所示:

InputStream is = this.getClass().getClassLoader().getResourceAsStream("/Snake/lib/game_over.ttf");

注意/ 之前的Snake

如果不使用绝对名称,我认为Java会在类的包中搜索,而不是在Jar的根级别。

2:您使用了两次 InputStream,因为您实际上调用了两次 Font.createFont(...)。至少第二次,输入流要么被关闭,要么在最后,没有其他内容可以读取,因此第二次调用将失败。只需使用加载的字体进行注册:

GAMEOVER_FONT = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(200f);   
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
ge.registerFont(GAMEOVER_FONT); // <-- do not load 2nd time
g.setFont(GAMEOVER_FONT);

【讨论】:

  • 当我在命令行上运行它时仍然无法工作我得到java.io.IOException: Problem reading font data.
  • 检查是否is == null。如果是null,则找不到资源。如果它不为null,则找到tif文件,但还有其他问题。
  • 我已经用与新异常相关的第二点更新了我的答案
  • 还是不行,InputStream为空
【解决方案2】:

尽管我认为在您的用例中结果应该相同,但请尝试:

this.getClass().getResourceAsStream()

代替:

this.getClass().getClassLoader().getResourceAsStream()

注意getClassLoader() 的区别。

也许类加载器层次结构有所不同,它可以为您提供不同的输出。

此外,您可以尝试将字体放在您的类、Java 输出目录中,然后从那里读取它,以检查字体是否存在实际问题。

【讨论】:

  • InputStream 会干扰序列化吗?之后我的序列化停止工作
  • 不应该安德烈。请问,你能解释一下你的新问题吗?
  • 我觉得在 cmets 上发帖太长了,我应该打开另一个问题吗?但无论如何我得到的错误是java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream
  • 如你所愿,安德烈。如果您认为新问题与此问题密切相关,请修改问题,虽然我认为最好创建一个新问题,但最好每个问题只发布一个 question 以便帮助人们识别问题中正在解决的实际问题。
  • 我现在得走了,但也很乐意在一大早复习新问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-05-03
  • 1970-01-01
  • 1970-01-01
  • 2021-03-13
  • 1970-01-01
  • 2010-09-24
  • 2011-12-07
相关资源
最近更新 更多