I am implementing a "Load File" functionality in my Java application - sometimes the file might be on a network share which can take a little while to read. Once the user has selected a file to load, I am changing the mouse cursor to Cursor.WAIT_CURSOR
. This works fine on Windows, but I am getting strange results on both Java 7u75 and 8u45 on Mac OS 10.9.5. I have tried changing the cursor on both the JFrame
component as well as the GlassPane
, but I am seeing the same results.
Basically, on Mac OS, if the mouse interacts with the JFileChooser
in any way then the cursor isn't changed, but if I use the keyboard to select a file then it works as expected and the cursor is changed.
This looks a bit bug like, but lookig for some wisdom from someone who might have come across this before and conquered it? I have put together an SSCCE below to demonstrate the problem.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SSCCE extends JFrame implements ActionListener {
private final SSCCE T = this;
private Component gP = getRootPane().getGlassPane();
private JMenuBar mBar;
private JMenu mFile;
private JMenuItem miLoad;
public SSCCE() {
setTitle("SSCCE");
setSize(960, 640);
setDefaultCloseOperation(EXIT_ON_CLOSE);
mBar = new JMenuBar();
mFile = new JMenu("File");
miLoad = new JMenuItem("Load");
miLoad.addActionListener(this);
mFile.add(miLoad);
mBar.add(mFile);
setJMenuBar(mBar);
setLocationRelativeTo(null);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == miLoad) {
JFileChooser fc = new JFileChooser();
fc.showDialog(this, "Test");
updateCursor(Cursor.WAIT_CURSOR);
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() {
try {
Thread.sleep(5000);
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void done() {
updateCursor(Cursor.DEFAULT_CURSOR);
JOptionPane.showMessageDialog(T, "OK", "Status", JOptionPane.PLAIN_MESSAGE);
}
}.execute();
}
}
private void updateCursor(final int c) {
gP.setCursor(Cursor.getPredefinedCursor(c));
gP.setVisible(c != Cursor.DEFAULT_CURSOR);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new SSCCE();
}
});
}
}