如何最大化面板及其组件的渲染速度?
How can I maximize rendering speed of a panel and its components?
我创建了一个简单的启动画面,它基本上是一个 JFrame
和一个背景图像,两个 JLabels
和一个 JProgressbar
。当我只渲染带有背景图像的帧时,大约需要 200 毫秒,这是启动画面的好时机。
但是只要我添加一个 JLabel(使用 Sansserif 字体)就需要两秒钟!因此,创建字符串的时间是渲染图像的 9 倍。
如何降低 JLabel 或面板的渲染速度?
private static final Dimension LOADINGSCREEN_DIMENSION = new Dimension(400, 400);
private LoadingScreen() {
super();
this.setUndecorated(true);
this.setResizable(false);
this.setLayout(new BorderLayout(0, 0));
this.setSize(LOADINGSCREEN_DIMENSION);
this.setPreferredSize(LOADINGSCREEN_DIMENSION);
this.setContentPane(createContentPane());
//UNCOMMENT THIS LINE and it will take about 2 seconds to create
//this.add(createInformationLabel(), BorderLayout.SOUTH);
//Set location and pack
final Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation(dim.width/2-this.getSize().width/2, dim.height/2-this.getSize().height/2);
}
private JLabel createInformationLabel() {
JLabel infoLabel = new JLabel("Label");
infoLabel.setFont(new Font("SansSerif", Font.PLAIN, 12));
infoLabel.setHorizontalAlignment(SwingConstants.RIGHT);
infoLabel.setBorder(new EmptyBorder(50, 0, 10, 20));
infoLabel.setOpaque(false);
return infoLabel;
}
这与渲染速度无关。所有这些的渲染速度都在几十毫秒的数量级。
您看到的性能损失与加载 classes 有关。在可以呈现 JFrame
之前,需要加载它的 class,以及它所依赖的所有 class,依此类推。然后你正在实例化一个JLabel
。这个 class 需要加载,以及它所依赖的所有 classes。然后你正在实例化一个Font
,所以所有与字体相关的classes都需要加载。我不知道,但甚至可能会发生一些 "font subsystem initialization"。你明白了。
因此,就目前而言,您无法避免这种开销。
您可以尝试跳过标签并使用 "graphics" 自己渲染文本,但我不能保证您会看到这种方式的任何改进。
你也可以看看SplashScreen
这个组件,希望能优化一下,尽量少涉及class,加载尽可能快,但我没有这方面的经验。而且,您可能无法通过 JLabel
或自己渲染来向其中添加文本,或者如果您这样做,您可能会遭受当前遇到的所有开销。
我还有另一个答案给你。您的问题可能与此问题有关,该问题仍未解决:
JDK-8179209 文本渲染初始化时间慢
https://bugs.openjdk.java.net/browse/JDK-8179209
简而言之,javaswing加载字体的时间比较长,没有办法解决这个问题,只能在后台开始加载字体,同时继续做其他应用程序启动相关的事情正在加载字体而不尝试呈现任何文本,然后在加载字体后最终开始呈现文本。 openjdk 问题包含一些实现此目的的示例代码。
我创建了一个简单的启动画面,它基本上是一个 JFrame
和一个背景图像,两个 JLabels
和一个 JProgressbar
。当我只渲染带有背景图像的帧时,大约需要 200 毫秒,这是启动画面的好时机。
但是只要我添加一个 JLabel(使用 Sansserif 字体)就需要两秒钟!因此,创建字符串的时间是渲染图像的 9 倍。
如何降低 JLabel 或面板的渲染速度?
private static final Dimension LOADINGSCREEN_DIMENSION = new Dimension(400, 400);
private LoadingScreen() {
super();
this.setUndecorated(true);
this.setResizable(false);
this.setLayout(new BorderLayout(0, 0));
this.setSize(LOADINGSCREEN_DIMENSION);
this.setPreferredSize(LOADINGSCREEN_DIMENSION);
this.setContentPane(createContentPane());
//UNCOMMENT THIS LINE and it will take about 2 seconds to create
//this.add(createInformationLabel(), BorderLayout.SOUTH);
//Set location and pack
final Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
this.setLocation(dim.width/2-this.getSize().width/2, dim.height/2-this.getSize().height/2);
}
private JLabel createInformationLabel() {
JLabel infoLabel = new JLabel("Label");
infoLabel.setFont(new Font("SansSerif", Font.PLAIN, 12));
infoLabel.setHorizontalAlignment(SwingConstants.RIGHT);
infoLabel.setBorder(new EmptyBorder(50, 0, 10, 20));
infoLabel.setOpaque(false);
return infoLabel;
}
这与渲染速度无关。所有这些的渲染速度都在几十毫秒的数量级。
您看到的性能损失与加载 classes 有关。在可以呈现 JFrame
之前,需要加载它的 class,以及它所依赖的所有 class,依此类推。然后你正在实例化一个JLabel
。这个 class 需要加载,以及它所依赖的所有 classes。然后你正在实例化一个Font
,所以所有与字体相关的classes都需要加载。我不知道,但甚至可能会发生一些 "font subsystem initialization"。你明白了。
因此,就目前而言,您无法避免这种开销。
您可以尝试跳过标签并使用 "graphics" 自己渲染文本,但我不能保证您会看到这种方式的任何改进。
你也可以看看SplashScreen
这个组件,希望能优化一下,尽量少涉及class,加载尽可能快,但我没有这方面的经验。而且,您可能无法通过 JLabel
或自己渲染来向其中添加文本,或者如果您这样做,您可能会遭受当前遇到的所有开销。
我还有另一个答案给你。您的问题可能与此问题有关,该问题仍未解决:
JDK-8179209 文本渲染初始化时间慢
https://bugs.openjdk.java.net/browse/JDK-8179209
简而言之,javaswing加载字体的时间比较长,没有办法解决这个问题,只能在后台开始加载字体,同时继续做其他应用程序启动相关的事情正在加载字体而不尝试呈现任何文本,然后在加载字体后最终开始呈现文本。 openjdk 问题包含一些实现此目的的示例代码。