Java: изменение шрифтов пользовательского интерфейса (Nimbus) не работает! - PullRequest
6 голосов
/ 04 июня 2009

Я имею в виду эту ссылку на Nimbus .

Я попытался установить глобальный шрифт немного больше:

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

... работает только для меню, но ничего остальное (кнопки, метки).

Я пытался изменить шрифты меток и кнопок с помощью

UIManager.put("Button.font", new Font(Font.SANS_SERIF, 0, 16));
UIManager.put("Label.font", new Font(Font.SANS_SERIF, 0, 16));

но шрифт остается .

Единственное, что сработало для меня, это получение шрифта:

someButton.setFont(someButton.getFont().deriveFont(16f));

Но это не вариант, так как это должно быть сделано для каждого элемент вручную.

Обратите внимание, что получение шрифта для UIManager тоже не работает :

UIManager.put("Label.font",
    UIManager.getFont("Label.font").deriveFont(16f));

Я тестировал все под Linux и Windows: такое же поведение.

Я просто не могу понять, как API может быть таким грязным. Если метод вызывается setFont (..) затем Я ожидаю, что установит шрифт. Если этот метод не удается установите шрифт в любых мыслимых обстоятельствах, тогда он не рекомендуется.

EDIT:
Эта проблема относится не только к Nimbus, но и к стандартному LAF.

Ответы [ 6 ]

8 голосов
/ 05 апреля 2010

Это работает с JDK6 и JDK7. Копируй + вставляй и веселись;)

Примечание: для JDK6 изменить
javax.swing.plaf.nimbus до
com.​sun.​java.​swing.​plaf.​nimbus.

Код

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

  });
 }

}
4 голосов
/ 06 октября 2011

Ленивые значения по умолчанию создаются ленивым, поэтому установка defaultFont до рисования экрана добавит шрифт к родительским настройкам по умолчанию, а не к настройкам по умолчанию.

Обходной путь: принудительно установите nimbus по умолчанию и установите значения по умолчанию:

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

Примечание: этот код более эффективен, чем переопределение getDefaults (), как предложено выше.

1 голос
/ 18 апреля 2013

Ответ в одной строке кода (при условии, что вы уже установили Nimbus LaF):

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

Конечно, вам нужно вызвать это, прежде чем создавать какие-либо компоненты графического интерфейса, т. Е. Прямо в вашем главном сразу после установки Nimbus LaF.

1 голос
/ 04 июня 2009

Оберните ваш шрифт с помощью FontUIResource . У меня была точно такая же проблема с цветами UIManager и ColorUIResource все исправил. Не копаясь в JDK, я думаю, что есть места, где компоненты ожидают (читай: проверьте через instanceof) UIResources (может быть, кто-то может это подтвердить)

1 голос
/ 04 июня 2009

Одна вещь, которая поражает меня по сей день, - то, что сеттеры LaF [setFont, setBackground, и т. Д.] Фактически не устанавливают реальные свойства. В спецификации сказано, что LaFs разрешено игнорировать пользовательские шрифты, цвета и т. Д. Вот почему GTKLaF полностью нарушен. Он использует системные настройки темы gtk, а не настройки программиста. IIRC Nimbus имеет отдельный пакетный закрытый класс, который содержит значения по умолчанию (NimbusDefaults?) И к которым нет легкого доступа.

Я предлагаю никогда с использованием GTK или Nimbus LAF, если вы планируете каким-либо образом настроить внешний вид.

Быстрый поиск в Google появляется это для GTK

Обсуждение этих проблем в нимбе можно найти здесь .

0 голосов
/ 04 июня 2009

Java LAF API немного неуклюже, но нет ничего лучше, чем проверить исходный код, чтобы получить ваши ответы.

Обратите внимание, что MetalLookAndFeel и Nimbus - это разные реализации, и свойства каждого из них не обязательно должны быть одинаковыми.

В следующих примерах используется 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);
      }
    });
  }
}

Это работает, потому что свойство "Label.font" существует в Metal, и оно правильно использует это свойство.

Вы можете проверить это так:

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