Joe*_*hel 3 java swing nullpointerexception look-and-feel
我正在为更大的GUI应用程序编写脚本.主应用程序窗口使用系统LookAndFeel,但我希望我的脚本的GUI使用Nimbus LookAndFeel.创建GUI后,我想将其设置LookAndFeel回原始版本.我觉得下面的SSCCE应该可以工作,但我NullPointerException在使用我的Component对象时会得到一个.
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
public class GUI extends JFrame {
private static LookAndFeel originalLookAndFeel = UIManager.getLookAndFeel();
static {
System.out.println("At start, look and feel is " + UIManager.getLookAndFeel().getName());
try {
setNimbusLookAndFeel();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("Look and feel changed to " + UIManager.getLookAndFeel().getName()
+ " before component creation");
}
private GridBagLayout gridBag = new GridBagLayout();
private JTabbedPane tabs = new JTabbedPane();
private JPanel selectionPanel = new JPanel(gridBag);
private JPanel infoPanel = new JPanel(gridBag);
private JPanel settingsPanel = new JPanel(gridBag);
public GUI() {
setWindowProperties();
setUpComponents();
addComponents();
try {
System.out.println("Setting to original, which is " + originalLookAndFeel.getName());
UIManager.setLookAndFeel(originalLookAndFeel);
System.out.println("Current look and feel is " + UIManager.getLookAndFeel().getName());
} catch (UnsupportedLookAndFeelException e) {
e.printStackTrace();
}
}
private void setWindowProperties() {
setLayout(gridBag);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(new Dimension(700, 600));
setTitle("fAmos Quester");
setResizable(false);
setLocationRelativeTo(null);
}
private static void setNimbusLookAndFeel() {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
}
}
} catch (Exception e) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e2) {
}
}
}
public void setUpComponents() {
tabs.addTab("Quest selection", selectionPanel);
tabs.addTab("Quest info", infoPanel);
tabs.addTab("Settings", settingsPanel);
selectionPanel.setPreferredSize(new Dimension(650, 500));
infoPanel.setPreferredSize(new Dimension(650, 500));
settingsPanel.setPreferredSize(new Dimension(650, 500));
}
private void addComponents() {
add(tabs);
}
public static void main(String[] args) {
new GUI().setVisible(true);
}
}
Run Code Online (Sandbox Code Playgroud)
作为一般规则,混合LAF并不是一个好主意.这个问题就是一个例子.
Nimbus LAF中有一些东西可能不允许你这样做.按原样运行代码.它会将LAF设置为System LAF然后重置LAF.在我的情况下,系统是Windows,它似乎工作正常.然后更改代码以使用Nimbus LAF.它似乎最初工作,但尝试调整框架大小,你会得到错误.因此,看起来Nimbus帧不能完全独立于当前的LAF工作.
import java.awt.*;
import java.awt.event.*;
import java.awt.GridBagLayout;
import javax.swing.*;
import javax.swing.UIManager.LookAndFeelInfo;
public class GUI2 extends JFrame {
private static LookAndFeel originalLookAndFeel = UIManager.getLookAndFeel();
/*
private GridBagLayout gridBag = new GridBagLayout();
private JTabbedPane tabs = new JTabbedPane();
private JPanel selectionPanel = new JPanel(gridBag);
private JPanel infoPanel = new JPanel(gridBag);
private JPanel settingsPanel = new JPanel(gridBag);
*/
private GridBagLayout gridBag;
private JTabbedPane tabs;
private JPanel selectionPanel;
private JPanel infoPanel;
private JPanel settingsPanel;
public GUI2() {
System.out.println("At start, look and feel is " + UIManager.getLookAndFeel().getName());
try {
// setNimbusLookAndFeel();
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Look and feel changed to " + UIManager.getLookAndFeel().getName()
+ " before component creation");
gridBag = new GridBagLayout();
setLayout(gridBag);
tabs = new JTabbedPane();
selectionPanel = new JPanel(gridBag);
infoPanel = new JPanel(gridBag);
settingsPanel = new JPanel(gridBag);
setUpComponents();
addComponents();
setWindowProperties();
Action reset = new AbstractAction()
{
public void actionPerformed(ActionEvent ae)
{
try {
System.out.println("Setting to original, which is " + originalLookAndFeel.getName());
UIManager.setLookAndFeel(originalLookAndFeel);
System.out.println("Current look and feel is " + UIManager.getLookAndFeel().getName());
} catch (UnsupportedLookAndFeelException e) {
//e.printStackTrace();
System.out.println(e.getMessage());
}
}
};
Timer timer = new Timer(500, reset);
timer.setRepeats(false);
timer.start();
}
private void setWindowProperties() {
// setLayout(gridBag);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("fAmos Quester");
// setResizable(false);
pack();
setLocationRelativeTo(null);
}
private void setNimbusLookAndFeel() {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
}
}
} catch (Exception e) {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e2) {
}
}
}
public void setUpComponents() {
tabs.addTab("Quest selection", selectionPanel);
tabs.addTab("Quest info", infoPanel);
tabs.addTab("Settings", settingsPanel);
selectionPanel.setPreferredSize(new Dimension(650, 500));
infoPanel.setPreferredSize(new Dimension(650, 500));
settingsPanel.setPreferredSize(new Dimension(650, 500));
}
private void addComponents() {
add(tabs);
}
public static void main(String[] args) {
new GUI2().setVisible(true);
}
}
Run Code Online (Sandbox Code Playgroud)
也许解决方案是使用Nimbus LAF创建组件,如上所述.但是,在取消激活帧之前,请勿重置LAF.然后,您可以尝试在每次激活帧时重置LAF.您将使用WindowListener来处理激活/停用的事件.