简体   繁体   English

Java JFileChooser在Metal L&F中导致NullPointerException

[英]Java JFileChooser causes NullPointerException in Metal L&F

I'm having issues showing JFileChooser s in Java. 我在用Java显示JFileChooser遇到问题。 When I try to display the dialog in any way, I get a NullPointerException. 当我尝试以任何方式显示对话框时,都会收到NullPointerException。 Since I'm working on a fairly complex Java project, I initially thought something in my code was wrong, so I wrote one of the simplest Swing projects I could think of: 由于我正在从事一个相当复杂的Java项目,因此最初我以为我的代码有问题,所以我写了一个我能想到的最简单的Swing项目:

package info.varden.so;

import javax.swing.JFileChooser;
import javax.swing.JFrame;

public class MetalFileChooserTest {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setSize(300, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        JFileChooser jfc = new JFileChooser();
        System.out.println("All well so far!");
        int result = jfc.showSaveDialog(frame);
    }

}

Even with this, I'm still getting the exception. 即使这样,我仍然有例外。 It reads as follows: 内容如下:

Exception in thread "main" java.lang.NullPointerException
    at javax.swing.plaf.metal.MetalFileChooserUI$IndentIcon.getIconWidth(MetalFileChooserUI.java:892)
    at javax.swing.SwingUtilities.layoutCompoundLabelImpl(SwingUtilities.java:943)
    at javax.swing.SwingUtilities.layoutCompoundLabel(SwingUtilities.java:870)
    at javax.swing.plaf.basic.BasicLabelUI.layoutCL(BasicLabelUI.java:76)
    at javax.swing.plaf.basic.BasicLabelUI.getPreferredSize(BasicLabelUI.java:221)
    at javax.swing.JComponent.getPreferredSize(JComponent.java:1642)
    at javax.swing.plaf.basic.BasicListUI.updateLayoutState(BasicListUI.java:1346)
    at javax.swing.plaf.basic.BasicListUI.maybeUpdateLayoutState(BasicListUI.java:1294)
    at javax.swing.plaf.basic.BasicListUI$Handler.valueChanged(BasicListUI.java:2611)
    at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:167)
    at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:147)
    at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:194)
    at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:388)
    at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:398)
    at javax.swing.DefaultListSelectionModel.setSelectionInterval(DefaultListSelectionModel.java:442)
    at javax.swing.JList.setSelectedIndex(JList.java:2179)
    at javax.swing.plaf.basic.BasicComboPopup.setListSelection(BasicComboPopup.java:1127)
    at javax.swing.plaf.basic.BasicComboPopup.access$300(BasicComboPopup.java:46)
    at javax.swing.plaf.basic.BasicComboPopup$Handler.itemStateChanged(BasicComboPopup.java:965)
    at javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1205)
    at javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1262)
    at javax.swing.JComboBox.contentsChanged(JComboBox.java:1309)
    at javax.swing.AbstractListModel.fireContentsChanged(AbstractListModel.java:100)
    at javax.swing.plaf.metal.MetalFileChooserUI$DirectoryComboBoxModel.setSelectedItem(MetalFileChooserUI.java:1015)
    at javax.swing.plaf.metal.MetalFileChooserUI$DirectoryComboBoxModel.addItem(MetalFileChooserUI.java:986)
    at javax.swing.plaf.metal.MetalFileChooserUI$DirectoryComboBoxModel.access$900(MetalFileChooserUI.java:911)
    at javax.swing.plaf.metal.MetalFileChooserUI.doDirectoryChanged(MetalFileChooserUI.java:659)
    at javax.swing.plaf.metal.MetalFileChooserUI.access$1200(MetalFileChooserUI.java:33)
    at javax.swing.plaf.metal.MetalFileChooserUI$5.propertyChange(MetalFileChooserUI.java:748)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:339)
    at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:276)
    at java.awt.Component.firePropertyChange(Component.java:8170)
    at javax.swing.JFileChooser.setCurrentDirectory(JFileChooser.java:568)
    at javax.swing.JFileChooser.<init>(JFileChooser.java:334)
    at javax.swing.JFileChooser.<init>(JFileChooser.java:286)
    at info.varden.so.MetalFileChooserTest.main(MetalFileChooserTest.java:12)

The string "All well so far!" 字符串“到目前为止一切顺利!” is never printed to the console either, apparently because the constructor is causing the crash. 也不会打印到控制台,这显然是因为构造函数导致崩溃。 I obviously tested around a bit and found that I could only reproduce this on the Metal look and feel. 我显然经过了一些测试,发现只能在Metal外观上重现此效果。 Running Nimbus worked perfectly fine. 运行Nimbus效果很好。 I'm developing in NetBeans IDE 8.0, targeting Java 6 (JDK 1.6.0_45), and have that JDK installed in addition to JDK 1.7.0_55. 我正在针对Java 6(JDK 1.6.0_45)的NetBeans IDE 8.0中进行开发,除JDK 1.7.0_55外还安装了该JDK。 I also tried to switch constructors to the one taking a String path as parameter, to no avail. 我还尝试将构造函数切换为以String路径为参数的构造函数,但无济于事。 And no one else seem to be having this problem, as far as I can see. 据我所知,似乎没有其他人遇到这个问题。

I'm now wondering what could be causing such behavior, and how to solve it? 我现在想知道是什么原因导致这种行为,以及如何解决? An easy solution would be to switch to the Nimbus look and feel (which works), but some of my end users probably don't have that look and feel available on their systems. 一个简单的解决方案是切换到Nimbus外观(有效),但是我的某些最终用户可能在其系统上没有该外观。 Is there any other way, or is this simply a Java bug? 还有其他方法,还是仅仅是Java错误?

Any help would be highly appreciated. 任何帮助将不胜感激。

Looks like it only happened in Linux? 看起来这仅发生在Linux中吗? There is a workaround. 有一种解决方法。

LookAndFeel lookAndFeelBackup = UIManager.getLookAndFeel();
try {

  UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
// put your filechooser here
JFileChooser jfc = new JFileChooser();
// ...
try {
  UIManager.setLookAndFeel(lookAndFeel); // set look and feel back
} catch (UnsupportedLookAndFeelException e) {
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM