Skip to content

Commit bac7815

Browse files
committed
AbstractSwingUI: fix deadlock in chooseFile method
Closes #28.
1 parent 559cf1a commit bac7815

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

src/main/java/org/scijava/ui/swing/AbstractSwingUI.java

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.awt.event.WindowAdapter;
3838
import java.awt.event.WindowEvent;
3939
import java.io.File;
40+
import java.lang.reflect.InvocationTargetException;
4041

4142
import javax.swing.JFileChooser;
4243
import javax.swing.JMenu;
@@ -48,10 +49,12 @@
4849
import org.scijava.app.AppService;
4950
import org.scijava.display.Display;
5051
import org.scijava.event.EventService;
52+
import org.scijava.log.LogService;
5153
import org.scijava.menu.MenuService;
5254
import org.scijava.menu.ShadowMenu;
5355
import org.scijava.platform.event.AppMenusCreatedEvent;
5456
import org.scijava.plugin.Parameter;
57+
import org.scijava.thread.ThreadService;
5558
import org.scijava.ui.AbstractUserInterface;
5659
import org.scijava.ui.SystemClipboard;
5760
import org.scijava.ui.UIService;
@@ -90,6 +93,12 @@ public abstract class AbstractSwingUI extends AbstractUserInterface implements
9093
@Parameter
9194
private UIService uiService;
9295

96+
@Parameter
97+
private ThreadService threadService;
98+
99+
@Parameter
100+
private LogService log;
101+
93102
private SwingApplicationFrame appFrame;
94103
private SwingToolBar toolBar;
95104
private SwingStatusBar statusBar;
@@ -125,19 +134,31 @@ public SystemClipboard getSystemClipboard() {
125134

126135
@Override
127136
public File chooseFile(final File file, final String style) {
128-
final JFileChooser chooser = new JFileChooser(file);
129-
if (FileWidget.DIRECTORY_STYLE.equals(style)) {
130-
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
131-
}
132-
final int rval;
133-
if (FileWidget.SAVE_STYLE.equals(style)) {
134-
rval = chooser.showSaveDialog(appFrame);
137+
final File[] result = new File[1];
138+
try {
139+
// NB: We show the JFileChooser on the EDT because otherwise there could
140+
// be a deadlock, particularly on macOS. See scijava/scijava-ui-swing#28.
141+
threadService.invoke(() -> {
142+
final JFileChooser chooser = new JFileChooser(file);
143+
if (FileWidget.DIRECTORY_STYLE.equals(style)) {
144+
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
145+
}
146+
final int rval;
147+
if (FileWidget.SAVE_STYLE.equals(style)) {
148+
rval = chooser.showSaveDialog(appFrame);
149+
}
150+
else { // default behavior
151+
rval = chooser.showOpenDialog(appFrame);
152+
}
153+
if (rval == JFileChooser.APPROVE_OPTION) {
154+
result[0] = chooser.getSelectedFile();
155+
}
156+
});
135157
}
136-
else { // default behavior
137-
rval = chooser.showOpenDialog(appFrame);
158+
catch (final InvocationTargetException | InterruptedException exc) {
159+
log.error(exc);
138160
}
139-
if (rval != JFileChooser.APPROVE_OPTION) return null;
140-
return chooser.getSelectedFile();
161+
return result[0];
141162
}
142163

143164
@Override

0 commit comments

Comments
 (0)