我试图为整个应用程序全局更改字体,问题是,我只能这样做一次。这是帮助您重新创建问题的代码。
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package test;
import java.awt.Font;
import java.util.Enumeration;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/**
*
* @author osiris
*/
public class Test {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws InterruptedException {
// TODO code application logic here
JFrame frame = new JFrame();
frame.setSize(600, 600);
frame.setVisible(true);
JButton button = new JButton("test");
frame.add(button);
frame.repaint();
Thread.sleep(2000);
Font font = new Font("Berlin Sans FB",java.awt.Font.PLAIN,14);
Enumeration test = UIManager.getDefaults().keys();
while ( test.hasMoreElements() ) {
Object key = test.nextElement();
Object value = UIManager.get( key );
if ( value instanceof Font ) {
UIManager.put( key, font );
}
}
SwingUtilities.updateComponentTreeUI(frame);
Thread.sleep(2000);
Font font2 = new Font("Tempus Sans ITC",java.awt.Font.PLAIN,14);
test = UIManager.getDefaults().keys();
while ( test.hasMoreElements() ) {
Object key = test.nextElement();
Object value = UIManager.get( key );
if ( value instanceof Font ) {
UIManager.put( key, font2 );
}
}
SwingUtilities.updateComponentTreeUI(frame);
}
}
按钮上的字体只更改一次,为什么?为什么第二次不改变?
答案 0 :(得分:4)
对Container
设置/更改/修改值已经显示UIManager/UIDeafaults
已经显示的所有/所有更改都是Look and Feel相关问题,而不是必须调用
SwingUtilities.updateComponentTreeUI(frame);
编辑如果要在运行时更新字体,则必须更改FontUIResource而不是简单字体
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
public class SystemFontDisplayer extends JFrame {
private static final long serialVersionUID = 1L;
private JFrame frame = new JFrame("Nimbus UIDeafaults and Font");
private JComboBox fontsBox;
private javax.swing.Timer timer = null;
private JButton testButton = new JButton("testButton");
private JTextField testTextField = new JTextField("testTextField");
private JLabel testLabel = new JLabel("testLabel");
public SystemFontDisplayer() {
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
String[] fontFamilyNames = ge.getAvailableFontFamilyNames();
fontsBox = new JComboBox(fontFamilyNames);
fontsBox.setSelectedItem(0);
fontsBox.setRenderer(new ComboRenderer(fontsBox));
fontsBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
final String fontName = fontsBox.getSelectedItem().toString();
fontsBox.setFont(new Font(fontName, Font.PLAIN, 16));
start();
}
}
});
fontsBox.setSelectedItem(0);
fontsBox.getEditor().selectAll();
frame.setLayout(new GridLayout(4, 0, 20, 20));
frame.add(fontsBox);
frame.add(testButton);
frame.add(testTextField);
frame.add(testLabel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(200, 105);
frame.pack();
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
fontsBox.setPopupVisible(true);
fontsBox.setPopupVisible(false);
}
});
frame.setVisible(true);
}
private void start() {
timer = new javax.swing.Timer(750, updateCol());
timer.setRepeats(false);
timer.start();
}
public Action updateCol() {
return new AbstractAction("text load action") {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
final Font fnt = new Font(fontsBox.getSelectedItem().toString(), Font.PLAIN, 12);
final FontUIResource res = new FontUIResource(fnt);
UIManager.getLookAndFeelDefaults().put("Button.font", res);
UIManager.getLookAndFeelDefaults().put("TextField.font", res);
UIManager.getLookAndFeelDefaults().put("Label.font", res);
SwingUtilities.updateComponentTreeUI(frame);
}
};
}
public static void main(String arg[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
SystemFontDisplayer systemFontDisplayer = new SystemFontDisplayer();
}
});
}
private class ComboRenderer extends BasicComboBoxRenderer {
private static final long serialVersionUID = 1L;
private JComboBox comboBox;
final DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
private int row;
private ComboRenderer(JComboBox fontsBox) {
comboBox = fontsBox;
}
private void manItemInCombo() {
if (comboBox.getItemCount() > 0) {
final Object comp = comboBox.getUI().getAccessibleChild(comboBox, 0);
if ((comp instanceof JPopupMenu)) {
final JList list = new JList(comboBox.getModel());
final JPopupMenu popup = (JPopupMenu) comp;
final JScrollPane scrollPane = (JScrollPane) popup.getComponent(0);
final JViewport viewport = scrollPane.getViewport();
final Rectangle rect = popup.getVisibleRect();
final Point pt = viewport.getViewPosition();
row = list.locationToIndex(pt);
}
}
}
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (list.getModel().getSize() > 0) {
manItemInCombo();
}
final JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(list, value, row, isSelected, cellHasFocus);
final Object fntObj = value;
final String fontFamilyName = (String) fntObj;
setFont(new Font(fontFamilyName, Font.PLAIN, 16));
return this;
}
}
}
答案 1 :(得分:1)
默认值是在创建新UI组件且未指定特定覆盖时应用的值。
如果要更改默认值,则必须在创建第一帧之前执行此操作。
要在创建UI之后更改整个应用程序的字体,您需要迭代所有现有组件并更改其字体字段(如果字体具有不同的大小,则强制重绘并可能重新布局)。 / p>