2010-03-16 79 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