2010-03-16 29 views
4

所以我遇到的问题是我通过显示一个简单的菜单来启动我的应用程序。要正确调整文本大小并对齐,我需要获取字体指标,并且找不到快速执行此操作的方法。我测试了我的程序,它看起来像我用什么方法获取字体指标,第一次调用需要超过500毫秒!?因为启动我的应用程序所需的时间比所需的时间长得多。真的很慢获取字体指标

我不知道它是否是平台特定的,但为了以防万一,我在MacBook Pro上使用Mac OS 10.6.2(这里硬件不是问题)。

如果您知道更快地获取字体指标的方法,请帮忙。

我试过这3种方法获取字体指标,第一次调用总是非常慢,不管我选择哪种方法。

import java.awt.Font; 
import java.awt.FontMetrics; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.font.FontRenderContext; 
import java.awt.font.LineMetrics; 

import javax.swing.JFrame; 

public class FontMetricsTest extends JFrame { 
public FontMetricsTest() { 
    setVisible(true); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
} 

@Override 
public void paint(Graphics g) { 
    Graphics2D g2 = (Graphics2D) g; 

    Font font = new Font("Dialog", Font.BOLD, 10); 
    long start = System.currentTimeMillis(); 

    FontMetrics fontMetrics = g2.getFontMetrics(font); 
// LineMetrics fontMetrics1 = 
//  font.getLineMetrics("X", new FontRenderContext(null, false, false)); 
// FontMetrics fontMetrics2 = g.getFontMetrics(); 

    long end = System.currentTimeMillis(); 
    System.out.println(end - start); 
    g2.setFont(font); 
} 

public static void main(String[] args) { 
    new FontMetricsTest(); 
} 
} 
+0

我有该程序的下一次运行(操作系统,JDK 1.6.0_18)所述第一运行和20ms的〜0.6秒。所以可能与磁盘缓存中的字体文件有关? – 2010-03-16 15:02:01

+0

可能是与连接字体服务器相关的问题?(我听说有一个小程序会杀死运行字体服务器的机器(包括Solaris机器),但那已经是十多年前的事了)。我放入缓存清理问题,尽管我猜这是不行的如果图形对象可能应用了变换,则工作得很好。 – 2010-03-16 16:32:37

+1

(呵呵,还有一个'Font'的缓存,你可以在API文档中看到他们有一个'finalize',但没有'dispose' ......) – 2010-03-16 16:33:55

回答

1

没有真正的线索,为什么它很慢,但方法3,你不应该先调用'setFont'吗?

public void paint(Graphics g) { 
    g.setFont(font); 
    FontMetrics fm = g.getFontMetrics(); 
} 

它不会有所作为速度的角度来看,虽然:-(

而且,这有点不符合经济原则,以创建一个新的Font每次paint()被称为(发生了很多),你可以移动,为您的构造函数。但是,这不能成为问题在这里,因为你开始测量字体已被创建后,才一次。

2

虽然我不能告诉你怎么去解决这个问题本身,你可以使用此方法来确定何时启动它:

new BufferedImage(1, 1, BufferedImage.TYPE_BYTE_GRAY).createGraphics().getFontMetrics(); 

这很有用,因为您可以将它放在任何地方 - 例如,您可以在显示加载屏幕或其他东西时进行此操作。如果您在paint()期间使用Graphics对象,则仅限于渲染时进行初始化。

编辑:

事实上,这可以减少到:

FontUtilities.getFont2D(new Font("Dialog", 0, 12)); 

(慢速部分是getFont2D呼叫,而不是Font构造函数)

编辑2:

最后,这可以被缩减为:

sun.font.FontManagerFactory.getInstance(); 

问题是这个singleton类需要很长时间才能启动,因为它列举了全部是的系统字体。

编辑3:

有解决这个问题没有什么好办法,如果你想使用标准的图形系统。

+0

这对我有用,但我不得不使用'getFont2D' :我在'FontManagerFactory.getInstance'上测试了90ms,然后在我的特定字体(系统中缺少这个字体)上getFont2D'仍然是2700ms。 – lapo 2016-04-18 14:35:40