Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JFileChooser occasionally slow to instantiate #849

Open
charphi opened this issue Jun 7, 2024 · 5 comments
Open

JFileChooser occasionally slow to instantiate #849

charphi opened this issue Jun 7, 2024 · 5 comments

Comments

@charphi
Copy link

charphi commented Jun 7, 2024

JFileChooser is occasionally slow to instantiate.
This problem is difficult to replicate since it seems to appear on Windows when shortcuts target unavailable network drives.
There are also multiple layers of cache that interfere.

After some digging, I think that the source of the problem is the class javax.swing.filechooser.FileSystemView. Expecially:

  • FileSystemView#getChooserComboBoxFiles() -> its result may contains network drives on Windows
  • FileSystemView#getChooserShortcutPanelFiles()
  • FileSystemView#getSystemIcon(File)
  • FileSystemView#getSystemIcon(File, int, int)
  • FileSystemView#getSystemDisplayName(File)

My current solution is to call these methods in a background thread at startup in order to warmup Windows internal caches.
See https://github.com/jdemetra/jdplus-main/blob/ddf9ce62f5f89bdd957cac10f03017e01db141f8/jdplus-main-desktop/jdplus-toolkit-desktop-plugin/src/main/java/jdplus/toolkit/desktop/plugin/util/Installer.java#L284

A better solution would be to handle each call to FileSystemView in FlatLaf asynchronously but that might be difficult to program.
What do you think ?

@charphi
Copy link
Author

charphi commented Jun 11, 2024

Here is a screenshot to visualize the different components

Screenshot 2024-06-11 143323_2

@DevCharly
Copy link
Collaborator

Sounds actually like a Java issue, which should be fixed in Java for all L&Fs...

JFileChooser is occasionally slow to instantiate

What does "slow" mean? One second? Two seconds? Five seconds? Or more?

Could you measure the time that FileSystemView#getChooserComboBoxFiles() needs?
(call System.currentTimeMillis() or System.nanoTime() before and after invoking the above method and calculate the difference)

My current solution is to call these methods in a background thread at startup in order to warmup Windows internal caches.

Does this mean that, without that warmup code, opening file chooser is slow when opened the first time
and "normal" on subsequent openings?

A better solution would be to handle each call to FileSystemView in FlatLaf asynchronously but that might be difficult to program.

Unfortunately, that is not possible without rewriting the whole file chooser UI...
FlatLaf file chooser is based on MetalFileChooserUI.

Files for chooser combo box are filled in MetalFileChooserUI.DirectoryComboBoxModel in private method addItem():
https://github.com/openjdk/jdk/blob/7e55ed3b106ed08956d2d38b7c99fb81704667c9/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java#L1031

Private method addItem() is also invoked from another private method:
https://github.com/openjdk/jdk/blob/7e55ed3b106ed08956d2d38b7c99fb81704667c9/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java#L719

So even if we implement a subclass of MetalFileChooserUI.DirectoryComboBoxModel and re-implement addItem() functionality asynchronously, we still have the problem that the original addItem() method is invoked from elsewhere...

Re-implementing addItem() is also difficult (or impossible?) because it uses some Java internal classes/methods (e.g. FilePane.usesShellFolder() or ShellFolder.getNormalizedFile()).

@charphi
Copy link
Author

charphi commented Jul 4, 2024

What does "slow" mean? One second? Two seconds? Five seconds? Or more?

Unfortunately, I can't replicate the problem when I want to.
It seems to be a combination of a slow network and broken links.

On one occasion it took 3 to 5 seconds to open the JFileChooser dialogue box each time I tried.

I've since upgraded to Windows 11. Now it only takes almost 1 second to open JFileChooser the first time and a few hundred milliseconds the second time. Obviously there are some caches at play somewhere ...

@charphi
Copy link
Author

charphi commented Jul 4, 2024

Unfortunately, that is not possible without rewriting the whole file chooser UI...
FlatLaf file chooser is based on MetalFileChooserUI.

Indeed. The MetalFileChooserUI is a bit odd to override. What I've found so far:

  • FilePane.usesShellFolder() can be replaced by Java9 FileSystemView#getChooserComboBoxFiles()
  • ShellFolder.getNormalizedFile()) code can be copy-pasted somewhere else
  • MetalFileChooserUI.DirectoryComboBoxModel can be overriden
  • addItem() can be avoided by overriding MetalFileChooserUI#createPropertyChangeListener(JFileChooser) and intercepting directoryChanged and FileChooser.useShellFolder properties.

@charphi
Copy link
Author

charphi commented Jul 5, 2024

Here is a proof-of-concept to play with :
https://gist.github.com/charphi/cf386bcbf4cd562801c8dd5da95b8b6c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants