From 12d71f45a18874b54b278c0c6baec532cb175f7e Mon Sep 17 00:00:00 2001 From: Michael Bien Date: Fri, 3 Jan 2025 04:46:50 +0100 Subject: [PATCH] DirectoryChooserUI: reduce reflective win ShellFolder API usage - some internal methods are now public in FileSystemView and can be used instead of using reflection - remove calls to ShellFolder.getShellFolder(file) entirely this hopefully fixes the mysterious NPEs on windows caused by broken java.io.File instances with null paths. --- .../swing/dirchooser/DirectoryChooserUI.java | 65 ++++--------------- 1 file changed, 12 insertions(+), 53 deletions(-) diff --git a/ide/o.n.swing.dirchooser/src/org/netbeans/swing/dirchooser/DirectoryChooserUI.java b/ide/o.n.swing.dirchooser/src/org/netbeans/swing/dirchooser/DirectoryChooserUI.java index 43c406351d3b..a6ffcbe137fc 100644 --- a/ide/o.n.swing.dirchooser/src/org/netbeans/swing/dirchooser/DirectoryChooserUI.java +++ b/ide/o.n.swing.dirchooser/src/org/netbeans/swing/dirchooser/DirectoryChooserUI.java @@ -43,6 +43,7 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; +import java.io.FileNotFoundException; import java.io.IOException; import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; @@ -272,7 +273,7 @@ private void updateUseShellFolder() { useShellFolder = false; File[] roots = fileChooser.getFileSystemView().getRoots(); if (roots != null && roots.length == 1) { - File[] cbFolders = getShellFolderRoots(); + File[] cbFolders = fileChooser.getFileSystemView().getChooserComboBoxFiles(); if (cbFolders != null && cbFolders.length > 0 && Arrays.asList(cbFolders).contains(roots[0])) { useShellFolder = true; } @@ -328,54 +329,15 @@ private JComponent getPlacesBar() { return null; } } - - /** Reflection alternative of - * sun.awt.shell.ShellFolder.getShellFolder(file) - */ - private File getShellFolderForFile (File file) { - try { - Class clazz = Class.forName("sun.awt.shell.ShellFolder"); - return (File) clazz.getMethod("getShellFolder", File.class).invoke(null, file); - } catch (Exception exc) { - // reflection not succesfull, just log the exception and return null - Logger.getLogger(DirectoryChooserUI.class.getName()).log( - Level.FINE, "ShellFolder can't be used.", exc); - return null; - } - } - /** Reflection alternative of - * sun.awt.shell.ShellFolder.getShellFolder(dir).getLinkLocation() - */ - private File getShellFolderForFileLinkLoc (File file) { + private File getShellFolderForFileLinkLoc(File file) { try { - Class clazz = Class.forName("sun.awt.shell.ShellFolder"); - Object sf = clazz.getMethod("getShellFolder", File.class).invoke(null, file); - return (File) clazz.getMethod("getLinkLocation").invoke(sf); - } catch (Exception exc) { - // reflection not succesfull, just log the exception and return null - Logger.getLogger(DirectoryChooserUI.class.getName()).log( - Level.FINE, "ShellFolder can't be used.", exc); - return null; - } - - } - - /** Reflection alternative of - * sun.awt.shell.ShellFolder.get("fileChooserComboBoxFolders") - */ - private File[] getShellFolderRoots () { - try { - Class clazz = Class.forName("sun.awt.shell.ShellFolder"); - return (File[]) clazz.getMethod("get", String.class).invoke(null, "fileChooserComboBoxFolders"); - } catch (Exception exc) { - // reflection not succesfull, just log the exception and return null - Logger.getLogger(DirectoryChooserUI.class.getName()).log( - Level.FINE, "ShellFolder can't be used.", exc); + return fileChooser.getFileSystemView().getLinkLocation(file); + } catch (FileNotFoundException ex) { return null; } } - + private void createBottomPanel(JFileChooser fc) { bottomPanel = new JPanel(); bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.LINE_AXIS)); @@ -1864,11 +1826,9 @@ public String getName() { * Data model for a type-face selection combo-box. */ private class DirectoryComboBoxModel extends AbstractListModel implements ComboBoxModel { - Vector directories = new Vector<>(); - int[] depths = null; - File selectedDirectory = null; - JFileChooser chooser = getFileChooser(); - FileSystemView fsv = chooser.getFileSystemView(); + private final Vector directories = new Vector<>(); + private int[] depths = null; + private File selectedDirectory = null; public DirectoryComboBoxModel() { // Add the current directory to the model, and make it the @@ -1893,7 +1853,7 @@ private void addItem(File directory) { directories.clear(); if(useShellFolder) { - directories.addAll(Arrays.asList(getShellFolderRoots())); + directories.addAll(Arrays.asList(fileChooser.getFileSystemView().getChooserComboBoxFiles())); } else { directories.addAll(Arrays.asList(fileChooser.getFileSystemView().getRoots())); } @@ -1911,8 +1871,7 @@ private void addItem(File directory) { } // create File instances of each directory leading up to the top - File sf = useShellFolder? getShellFolderForFile(canonical) : canonical; - File f = sf; + File f = canonical; Vector path = new Vector<>(10); @@ -1940,7 +1899,7 @@ private void addItem(File directory) { } } calculateDepths(); - setSelectedItem(sf); + setSelectedItem(canonical); } private void calculateDepths() {