2010-10-11 156 views
5

有沒有辦法在Swing GTK LaF中更改默認字體大小?如何更改Swing GTK LookAndFeel中的默認字體大小?

GTK LaF似乎假設爲72dpi,因此所有字體只有在使用96dpi屏幕時應爲的大小的3/4。有關詳細信息,請參閱Fedora bug。在此期間,我希望找到解決方法,同時等待修復。

例如,我已經嘗試通過UIDefaults重置字體大小,例如推薦here,但是(同樣在那裏指出的)GTK LaF似乎忽略了這一點。

可以建立一個小部件的工廠,這也將設置所需的字體大小,用於創建我所有的Swing小部件,但是這將是大規模侵入性的,所以我想避免這條路線,如果有任何其他方式。

編輯:下不起作用:

public class GTKLaF extends com.sun.java.swing.plaf.gtk.GTKLookAndFeel { 
    @Override 
    public UIDefaults getDefaults() { 
    final float scale = 3f; 

    final UIDefaults defaults = super.getDefaults(); 

    final Map<Object,Object> changes = new HashMap<Object,Object>(); 

    for (Map.Entry<Object,Object> e : defaults.entrySet()) { 
     final Object key = e.getKey(); 
     final Object val = e.getValue(); 

     if (val instanceof FontUIResource) { 
     final FontUIResource ores = (FontUIResource) val; 
     final FontUIResource nres = 
      new FontUIResource(ores.deriveFont(ores.getSize2D()*scale)); 
     changes.put(key, nres); 
     System.out.println(key + " = " + nres); 
     } 
     else if (val instanceof Font) { 
     final Font ofont = (Font) val; 
     final Font nfont = ofont.deriveFont(ofont.getSize2D()*scale); 
     changes.put(key, nfont); 
     System.out.println(key + " = " + nfont); 
     } 
    } 

    defaults.putAll(changes); 

    return defaults; 
    } 
} 

你可能認爲這將打印至少有十幾個鍵值對,但它只有一個打印:TitledBorder.font。顯然GTLLookAndFeel不提供其他字體屬性,但是來自其他地方!

回答

1

似乎沒有辦法設置默認字體大小。然而,問題中引用的bug後來得到了修復,所以現在需要做這個工作。

0

您鏈接的代碼有問題。 UIDefaults.get(key)函數不必返回Font實例。它可能是一個javax.swing.plaf.FontUIResource實例。 下面的代碼片段找到所有已安裝的外觀,不是改變所有的字體大小在scale

float scale=1.1f; 
UIManager.LookAndFeelInfo looks[] = UIManager.getInstalledLookAndFeels(); 

for (UIManager.LookAndFeelInfo info : looks) { 

    //if you want to change LaF to a spesific LaF,such as "GTK" 
    //put here a if statement like: 
    //if(info.getClassName().contains("GTK")) 
    UIManager.setLookAndFeel(info.getClassName()); 

    UIDefaults defaults = UIManager.getDefaults(); 
    Enumeration newKeys = defaults.keys(); 

    while (newKeys.hasMoreElements()) { 
     Object obj = newKeys.nextElement(); 
     Object current = UIManager.get(obj); 
     if (current instanceof FontUIResource) { 
      FontUIResource resource = (FontUIResource) current; 
      defaults.put(obj, new FontUIResource(resource.deriveFont(resource.getSize2D()*scale))); 
      // System.out.printf("%50s : %s\n", obj, UIManager.get(obj)); 
     } else if (current instanceof Font) { 
      Font resource = (Font) current; 
      defaults.put(obj, resource.deriveFont(resource.getSize2D()*scale)); 
      // System.out.printf("%50s : %s\n", obj, UIManager.get(obj)); 
     } 
    } 
} 

我找到一些關於GTK的LaF問題的書,概括地說,三版的Java實例的比率。 看看吧here

+0

這是行不通的。對於GTK LaF,對於我設置比例因子的內容沒有什麼區別---這個代碼沒有明顯的效果。 – uckelman 2010-10-19 19:55:21

+0

@uckelman它是否適用於其他LaF? – 2010-10-19 20:02:46

+0

對UIManager.getInstalledLookAndFeels()的調用似乎會導致X的災難性崩潰,不知何故---機器會很難鎖定。如果我刪除這個和外部循環,你的代碼對Metal LaF來說是有效的。 – uckelman 2010-10-19 20:43:59

1

我的建議是創建您自己的GTKLookAndFeel的子類並使用它。

在你的子類中,我可能會覆蓋getDefaults()。在您的getDefaults()中,您可以獲取GTKLookAndFeel將要返回的UIDefaults,並在必要時調整它們。 (通過包裝或繼承他們重寫UIDefaults.getFont方法。)

獲取當前DPI與

int dpi = Toolkit.getDefaultToolkit().getScreenResolution(); 

,如果它不是72可以相應地更改字體大小。

編輯:您發佈的鏈接不起作用,我相信因爲GTKLookAndFeel會覆蓋所涉及的方法,並且不會讓其祖先的任何默認值通過。重寫它反過來應該允許你繞過這個問題。

+0

請參閱我對原始問題的編輯。重寫'getDefaults()'不起作用,因爲鍵不在那裏。 – uckelman 2010-10-20 21:32:38

+0

男人,這必須是一個設計不好的外觀。雖然我沒有看過源代碼,但我開始覺得他們只是硬編碼了這些值。作爲最後的手段,你可以將GTKLookAndFeel代碼複製到你自己的類中,然後在其中加入一些東西。 – 2010-10-20 21:59:29

+0

是的,我認爲這是一堆熱氣騰騰的東西。我給了你賞金,因爲(1)時間快到了,(2)你最接近答案。 (我懷疑得到這個權利將需要重寫更多的方法,可能在'com.sun.java.swing.plaf.gtk'中的其他類中。) – uckelman 2010-10-21 16:02:55

0

我花了很多時間搞清楚如何讓我們的應用在Ubuntu上體面,我來到這個黑客。 我試過像有人建議擴展GTKLookAndFeel,但由於它使用了很多本地調用GTKEngine,我意識到它不可行。 我希望這有助於

只需設置外觀後打電話給我砍checkGTKLookAndFeel()它減少了兩個點的字體標準:

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
try { 
    InvoicexUtil.checkGTKLookAndFeel(); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

public static void checkGTKLookAndFeel() throws Exception { 
    LookAndFeel look = UIManager.getLookAndFeel(); 
    if (!look.getID().equals("GTK")) return; 

    new JFrame(); 
    new JButton(); 
    new JComboBox(); 
    new JRadioButton(); 
    new JCheckBox(); 
    new JTextArea(); 
    new JTextField(); 
    new JTable(); 
    new JToggleButton(); 
    new JSpinner(); 
    new JSlider(); 
    new JTabbedPane(); 
    new JMenu(); 
    new JMenuBar(); 
    new JMenuItem(); 

    Object styleFactory; 
    Field styleFactoryField = look.getClass().getDeclaredField("styleFactory"); 
    styleFactoryField.setAccessible(true); 
    styleFactory = styleFactoryField.get(look); 

    Field defaultFontField = styleFactory.getClass().getDeclaredField("defaultFont"); 
    defaultFontField.setAccessible(true); 
    Font defaultFont = (Font) defaultFontField.get(styleFactory); 
    FontUIResource newFontUI; 
    newFontUI = new FontUIResource(defaultFont.deriveFont((float)(defaultFont.getSize() - 2f))); 
    defaultFontField.set(styleFactory, newFontUI); 

    Field stylesCacheField = styleFactory.getClass().getDeclaredField("stylesCache"); 
    stylesCacheField.setAccessible(true); 
    Object stylesCache = stylesCacheField.get(styleFactory); 
    Map stylesMap = (Map) stylesCache; 
    for (Object mo : stylesMap.values()) { 
     Field f = mo.getClass().getDeclaredField("font"); 
     f.setAccessible(true); 
     Font fo = (Font)f.get(mo); 
     f.set(mo, fo.deriveFont((float)(fo.getSize() - 2f))); 
    } 
} 

調用各種Swing組件構造函數初始化GTK風格。 不是很優雅,但它的作品