我正在为更大的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);
}
}
最佳答案
一般来说,混合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);
}
}
也许一个解决方案是像上面那样使用Nimbus LAF创建组件。但是,在停用框架之前,请勿重置LAF。然后,您可以在每次激活框架时尝试重置LAF。您将使用WindowListener来处理已激活/已禁用的事件。