|
37 | 37 | import java.awt.event.WindowAdapter;
|
38 | 38 | import java.awt.event.WindowEvent;
|
39 | 39 | import java.io.File;
|
| 40 | +import java.lang.reflect.InvocationTargetException; |
40 | 41 |
|
41 | 42 | import javax.swing.JFileChooser;
|
42 | 43 | import javax.swing.JMenu;
|
|
48 | 49 | import org.scijava.app.AppService;
|
49 | 50 | import org.scijava.display.Display;
|
50 | 51 | import org.scijava.event.EventService;
|
| 52 | +import org.scijava.log.LogService; |
51 | 53 | import org.scijava.menu.MenuService;
|
52 | 54 | import org.scijava.menu.ShadowMenu;
|
53 | 55 | import org.scijava.platform.event.AppMenusCreatedEvent;
|
54 | 56 | import org.scijava.plugin.Parameter;
|
| 57 | +import org.scijava.thread.ThreadService; |
55 | 58 | import org.scijava.ui.AbstractUserInterface;
|
56 | 59 | import org.scijava.ui.SystemClipboard;
|
57 | 60 | import org.scijava.ui.UIService;
|
@@ -90,6 +93,12 @@ public abstract class AbstractSwingUI extends AbstractUserInterface implements
|
90 | 93 | @Parameter
|
91 | 94 | private UIService uiService;
|
92 | 95 |
|
| 96 | + @Parameter |
| 97 | + private ThreadService threadService; |
| 98 | + |
| 99 | + @Parameter |
| 100 | + private LogService log; |
| 101 | + |
93 | 102 | private SwingApplicationFrame appFrame;
|
94 | 103 | private SwingToolBar toolBar;
|
95 | 104 | private SwingStatusBar statusBar;
|
@@ -125,19 +134,31 @@ public SystemClipboard getSystemClipboard() {
|
125 | 134 |
|
126 | 135 | @Override
|
127 | 136 | 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 | + }); |
135 | 157 | }
|
136 |
| - else { // default behavior |
137 |
| - rval = chooser.showOpenDialog(appFrame); |
| 158 | + catch (final InvocationTargetException | InterruptedException exc) { |
| 159 | + log.error(exc); |
138 | 160 | }
|
139 |
| - if (rval != JFileChooser.APPROVE_OPTION) return null; |
140 |
| - return chooser.getSelectedFile(); |
| 161 | + return result[0]; |
141 | 162 | }
|
142 | 163 |
|
143 | 164 | @Override
|
|
0 commit comments