简体   繁体   中英

Java JFileChooser causes NullPointerException in Metal L&F

I'm having issues showing JFileChooser s in Java. When I try to display the dialog in any way, I get a 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:

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. Running Nimbus worked perfectly fine. 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. I also tried to switch constructors to the one taking a String path as parameter, to no avail. 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. Is there any other way, or is this simply a Java bug?

Any help would be highly appreciated.

Looks like it only happened in 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) {
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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