代码之家  ›  专栏  ›  技术社区  ›  uckelman

如何更改Swing GTK LookAndFeel中的默认字体大小?

  •  5
  • uckelman  · 技术社区  · 16 年前

    GTK LaF似乎假定为72dpi,因此所有字体的大小只有使用96dpi屏幕时的3/4。看这个 Fedora bug 详细情况。我想在这段时间内找到一个解决办法,而我在等待解决办法。

    我已经试过通过 UIDefaults ,按建议 here 例如,但是(也注意到了)GTK LaF似乎忽略了这一点。

    我 能够 建立一个widget工厂,它也会为创建所有Swing widget设置所需的字体大小,但这将是一个巨大的入侵,所以如果有其他方法的话,我想避免使用这个路径。

    以下操作不起作用:

    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;
      }
    }
    

    4 回复  |  直到 16 年前
        1
  •  1
  •   Brad Mace Mike King    16 年前

    我的建议是创建自己的GTKLookAndFeel子类并使用它。

    getDefaults() . 在你的 获取默认值() UIDefaults 如果有必要的话,GTKLookAndFeel会回来调整它们。(通过包装或子类化它们并重写 UIDefaults.getFont 方法)

    获取当前DPI

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

    编辑:您发布的链接不起作用,我相信是因为GTKLookAndFeel重写了相关的方法,并且不允许其祖先的任何默认值通过。反过来重写它可以让您绕过这个问题。

        2
  •  1
  •   uckelman    15 年前

    似乎无法设置默认字体大小。但是,问题中引用的bug已经被修复,所以现在没有必要这样做。

        3
  •  0
  •   Ferid Gürbüz    16 年前

    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

        4
  •  0
  •   mceccarellitnx    11 年前

    我花了很多时间去弄清楚如何在ubuntu上让我们的应用程序变得体面,然后我就遇到了这个问题。 我尝试过像有人建议的那样扩展GTKLookAndFeel,但由于它使用了许多本地的GTKEngine调用,我意识到这是不可行的。 我希望这有帮助

    在设置了look and feel call my hack 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样式。