Java: Altering UI fonts (Nimbus) doesn't work!

后端 未结 6 1259
傲寒
傲寒 2020-12-30 12:21

I\'m referring to this Nimbus reference.

I tried to set global Font to be slightly larger:

UIManager.put(\"defaultFont\", new Font(Font.SANS_SERIF,         


        
相关标签:
6条回答
  • 2020-12-30 12:54

    The nimbus defaults are lazy created so setting 'defaultFont' before the screen is painted, will add the font to the parent defaults, and not to the nimbus defaults.

    Workaround: force nimbus to initialize the defaults and set then the defaults:

    NimbusLookAndFeel laf = new NimbusLookAndFeel();
    UIManager.setLookAndFeel(laf);
    laf.getDefaults().put("defaultFont", new Font("Monospaced", Font.BOLD, 12));
    

    Note: this code is more efficient then overriding getDefaults(), as suggested above.

    0 讨论(0)
  • 2020-12-30 12:57

    Wrap your Font with FontUIResource. I had the exact same problem with UIManager colors and ColorUIResource fixed everything. Without digging through the JDK, I think there are some places where components expect (read: check via instanceof) for UIResources (maybe someone can confirm this)

    0 讨论(0)
  • 2020-12-30 12:58

    One thing that amazes me to this day is that the LaF setters [setFont, setBackground, etc] do not actually set real properties. The spec says that LaFs are allowed to ignore user set fonts, colors, etc. This is why GTKLaF is completely broken. It uses the system gtk theme settings, not the programmer's settings. IIRC Nimbus has a separate, package private class that contains defaults (NimbusDefaults?) and can't be easily accessed.

    I suggest never using GTK or Nimbus LAF if you plan on customizing the look in any way.

    A quick google search turns up this for GTK

    A discussion about these problems in nimbus can be found here.

    0 讨论(0)
  • 2020-12-30 13:07

    This works with JDK6 and JDK7. Copy+paste and have fun ;)

    Note: for JDK6, change
    javax.swing.plaf.nimbus to
    com.​sun.​java.​swing.​plaf.​nimbus.

    Code

    import java.awt.*;
    import java.lang.reflect.*;
    import javax.swing.*;
    import javax.swing.plaf.nimbus.*;
    
    public class Main {
    
     public static void main(String[] args)
       throws InterruptedException, InvocationTargetException {
    
      SwingUtilities.invokeAndWait(new Runnable() {
    
       @Override
       public void run() {
        try {
         UIManager.setLookAndFeel(new NimbusLookAndFeel() {
    
          @Override
          public UIDefaults getDefaults() {
           UIDefaults ret = super.getDefaults();
           ret.put("defaultFont",
             new Font(Font.MONOSPACED, Font.BOLD, 16)); // supersize me
           return ret;
          }
    
         });
    
         new JFrame("Hello") {
    
          {
           setDefaultCloseOperation(EXIT_ON_CLOSE);
           setLayout(new FlowLayout(FlowLayout.LEFT));
    
           setSize(500, 500);
           setLocationRelativeTo(null);
    
           add(new JLabel("someLabel 1"));
           add(new JButton("someButton 1"));
           add(new JLabel("someLabel 2"));
           add(new JButton("someButton 2"));
    
           setVisible(true);
          }
    
         };     
        } catch (Exception ex) {
         throw new Error(ex);
        }
       }
    
      });
     }
    
    }
    
    0 讨论(0)
  • 2020-12-30 13:09

    The answer in a single line of code (assuming you have already set Nimbus LaF):

    UIManager.getLookAndFeelDefaults().put("defaultFont", new Font(Font.SANS_SERIF, 0, 20));

    Of course, you need to call this before you create any GUI components, i.e. right in your main just after setting Nimbus LaF.

    0 讨论(0)
  • 2020-12-30 13:11

    Java LAF API is a little bit clumsy, but there is nothing better than check the source code to get your answers.

    Note that MetalLookAndFeel and Nimbus are different implementations and the properties for each one doesn't have to be the same.

    The following examples use the MetalLookAndFeel.

    package com.stackoverflow.laf.font;
    
    import java.awt.Font;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.SwingUtilities;
    import javax.swing.UIManager;
    
    public class SetFontExample {
    
      public static void main(String[] args) {
    
        SwingUtilities.invokeLater(new Runnable() {
          @Override public void run() {
            UIManager.put("Label.font", new Font(Font.SANS_SERIF, 0, 20));
            try {
              UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
            } catch (Exception e) {
              e.printStackTrace();
            }
    
            JFrame frame = new JFrame("Set font example");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new JLabel("Font test"));
            frame.pack();
            frame.setVisible(true);
          }
        });
      }
    }
    

    This works because the property "Label.font" exists on Metal and it uses that property correctly.

    You you can check it this way:

    package com.stackoverflow.laf;
    
    import javax.swing.SwingUtilities;
    import javax.swing.UIDefaults;
    import javax.swing.UIManager;
    
    public class ListLAFUIDefaults {
    
      public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
          @Override public void run() {
            try {
              // Choose LAF
              UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
            } catch (Exception e) {
              e.printStackTrace();
            }
            UIDefaults defaults = UIManager.getLookAndFeel().getDefaults();
            System.out.println(defaults);
    
            // Check a property
            String propertyKey = "defaultFont";
            System.out.println(UIManager.getLookAndFeel().getName() +
                (defaults.containsKey(propertyKey) ? " contains " : " doesn't contain ") +
                "property " + propertyKey);
          }
        });
      }
    }
    
    0 讨论(0)
提交回复
热议问题