Swing UIManager.put似乎不能正常工作。错误与否?

时间:2018-01-23 21:41:45

标签: java swing uimanager

我一直在使用UIManger.put全局更改标签的字体,但似乎它的工作方式不一致。有时候,有时却没有。 UIManager确实将新值保存在它的地图上。

例如,如果您使用:

final Font labelFont = new Font("Source Sans Pro", 0, 24);
UIManager.put("Label.font", labelFont);

您在创建标签之前/之后使用:

System.out.println(UIManager.get("Label.font"));

它返回

java.awt.Font[family=Source Sans Pro,name=Source Sans Pro,style=plain,size=24]

但标签的字体不会一直改变。什么是错的?

我试图改变调度线程上的属性并将其从中删除,但结果是一样的。

工作正常: working right

工作错误: working wrong

接下来的两个例子都有同样的问题。

这是一个例子,尝试多次,你会看到,除非我是我的电脑上有一些问题(我尝试了30次,没有夸张,没有任何问题,但它确实发生在即):

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public final class ElVecino {
  private JFrame frame;

  public ElVecino() {
    Locale.setDefault(Locale.forLanguageTag("es-CL"));
  }

  public static void main(String[] args) {
    final ElVecino application = new ElVecino();
    application.setLookAndFeel();
    try {
      SwingUtilities.invokeAndWait(() -> {
        application.createAndShowGUI();
      });
    } catch (InterruptedException | InvocationTargetException exception) {
      Logger.getLogger(ElVecino.class.getName()).log(Level.SEVERE, null, exception);
    }
  }

  public void createAndShowGUI() {
    frame = new JFrame("testApp");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    final JPanel contentPane = (JPanel)frame.getContentPane();

    System.out.println(UIManager.get("Label.font"));
    final JLabel label = new JLabel("Cargando...");
    contentPane.add(label, BorderLayout.CENTER);

    frame.setPreferredSize(new Dimension(800, 600));
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
    System.out.println(UIManager.get("Label.font"));
  }
  /**
   * 
   */
  public void setLookAndFeel() {
    try {
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
        if ("Nimbus".equals(info.getName())) {
          javax.swing.UIManager.setLookAndFeel(info.getClassName());
          break;
        }
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException exception) {
      Logger.getLogger(ElVecino.class.getName()).log(Level.SEVERE, null, exception);
    }
    final Font labelFont = new Font("Source Sans Pro", 0, 24);
    UIManager.put("Label.font", labelFont);
  }
}

这是将每个GUI方法放在调度线程上的另一个示例,也给我同样的问题,只是尝试多次

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public final class ElVecino {
  private JFrame frame;

  public ElVecino() {
    Locale.setDefault(Locale.forLanguageTag("es-CL"));
  }

  public static void main(String[] args) {
    final ElVecino application = new ElVecino();
    SwingUtilities.invokeLater(() -> {
      application.setLookAndFeel();
      application.createAndShowGUI();
    });
  }

  public void createAndShowGUI() {
    frame = new JFrame("testApp");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    final JPanel contentPane = (JPanel)frame.getContentPane();

    final JLabel label = new JLabel("Cargando...");
    contentPane.add(label, BorderLayout.CENTER);

    frame.setPreferredSize(new Dimension(800, 600));
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
  /**
   * 
   */
  public void setLookAndFeel() {
    try {
      for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels())
        if ("Nimbus".equals(info.getName())) {
          javax.swing.UIManager.setLookAndFeel(info.getClassName());
          break;
        }
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException exception) {
      Logger.getLogger(ElVecino.class.getName()).log(Level.SEVERE, null, exception);
    }
    final Font labelFont = new Font("Source Sans Pro", 0, 24);
    final Font textFieldFont =  new Font("Source Code Pro", 0, 24);
    UIManager.put("Label.font", labelFont);
    UIManager.put("TextField.font", textFieldFont);
    UIManager.put("TextArea.font", textFieldFont);
    UIManager.put("ProgressBar.font", labelFont);

  }
}

2 个答案:

答案 0 :(得分:0)

  

我认为必须有一些关于使用我不知道的UIManger.put的信息

不是关于UIManager,而是关于Swing的一般情况:

  1. 应在Event Dispatch Thread上创建Swing组件。有关详细信息,请阅读Concurrency上Swing教程中的部分。所以我也会在EDT中设置UIManager默认值。

  2. Swing教程建议使用invokeLater(...),而不是InvokeAndWait(...)。有关如何构建代码的示例,请参阅How to Use Labels中的LabelDemo示例代码。

答案 1 :(得分:0)

设置了挥杆属性后,您需要调用SwingUtilities.updateComponentTreeUi()