Skip to content

Commit 2ffb227

Browse files
committed
Drag-n-drop on creation dialog.
1 parent 4baf524 commit 2ffb227

File tree

4 files changed

+133
-35
lines changed

4 files changed

+133
-35
lines changed

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/resolver/CancelStatus.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,11 @@ public interface CancelStatus {
66

77
public boolean isCancelled();
88

9+
10+
public static CancelStatus notCancelable() {
11+
return new CancelStatus() {
12+
@Override public boolean isCancelled() { return false; }
13+
@Override public void cancel() { }
14+
};
15+
}
916
}

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/resolver/DataSetResolver.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,7 @@ public boolean isEnrichmentFile() {
5151

5252
public static List<DataSetParameters> guessDataSets(Path rootFolder, CancelStatus cancelStatus) {
5353
if(cancelStatus == null) {
54-
cancelStatus = new CancelStatus() {
55-
@Override public boolean isCancelled() { return false; }
56-
@Override public void cancel() { }
57-
};
54+
cancelStatus = CancelStatus.notCancelable();
5855
}
5956

6057
// First test if rootFolder is itself a GSEA results folder

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/resolver/ResolverTask.java

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.baderlab.csplugins.enrichmentmap.resolver;
22

33
import java.io.File;
4+
import java.nio.file.Files;
45
import java.nio.file.Path;
6+
import java.util.ArrayList;
57
import java.util.List;
68

79
import org.cytoscape.work.AbstractTask;
@@ -10,25 +12,35 @@
1012

1113
public class ResolverTask extends AbstractTask implements ObservableTask, CancelStatus {
1214

13-
private final Path root;
14-
private List<DataSetParameters> results;
15+
private final List<Path> folders = new ArrayList<>();
16+
private final List<DataSetParameters> results = new ArrayList<>();
1517

1618
public ResolverTask(Path root) {
17-
this.root = root;
19+
folders.add(root);
1820
}
1921

2022
public ResolverTask(File root) {
2123
this(root.toPath());
2224
}
2325

26+
public ResolverTask(List<File> files) {
27+
for(File file : files)
28+
folders.add(file.toPath());
29+
}
30+
2431
@Override
2532
public void run(TaskMonitor taskMonitor) throws Exception {
2633
taskMonitor.setTitle("EnrichmentMap");
2734
taskMonitor.setStatusMessage("Scanning Folder for Data Sets");
2835

29-
results = DataSetResolver.guessDataSets(root, this);
30-
if(results.isEmpty() && !cancelled) {
31-
throw new RuntimeException("No Data Sets found under: " + root);
36+
for(Path path : folders) {
37+
if(cancelled)
38+
break;
39+
40+
if(Files.isDirectory(path)) {
41+
List<DataSetParameters> dataSets = DataSetResolver.guessDataSets(path, (CancelStatus)this);
42+
results.addAll(dataSets);
43+
}
3244
}
3345
}
3446

EnrichmentMapPlugin/src/main/java/org/baderlab/csplugins/enrichmentmap/view/creation/MasterDetailDialogPage.java

Lines changed: 107 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,28 @@
44
import java.awt.CardLayout;
55
import java.awt.Color;
66
import java.awt.Component;
7+
import java.awt.datatransfer.DataFlavor;
8+
import java.awt.datatransfer.UnsupportedFlavorException;
9+
import java.awt.dnd.DropTargetAdapter;
10+
import java.awt.dnd.DropTargetDragEvent;
11+
import java.awt.dnd.DropTargetDropEvent;
12+
import java.awt.dnd.DropTargetEvent;
13+
import java.awt.dnd.DropTargetListener;
714
import java.io.File;
15+
import java.io.IOException;
816
import java.util.ArrayList;
17+
import java.util.Arrays;
918
import java.util.Iterator;
1019
import java.util.List;
1120
import java.util.Map;
1221
import java.util.Optional;
22+
import java.util.TooManyListenersException;
1323
import java.util.function.Function;
1424
import java.util.stream.Collectors;
1525
import java.util.stream.Stream;
1626

1727
import javax.swing.BorderFactory;
28+
import javax.swing.DropMode;
1829
import javax.swing.GroupLayout;
1930
import javax.swing.GroupLayout.Alignment;
2031
import javax.swing.JButton;
@@ -29,6 +40,7 @@
2940
import javax.swing.ListCellRenderer;
3041
import javax.swing.ListModel;
3142
import javax.swing.ListSelectionModel;
43+
import javax.swing.TransferHandler;
3244
import javax.swing.UIManager;
3345
import javax.swing.border.Border;
3446

@@ -229,7 +241,7 @@ private JPanel createTitlePanel() {
229241

230242
addButton.addActionListener(e -> addNewDataSetToList());
231243
deleteButton.addActionListener(e -> deleteSelectedItems());
232-
scanButton.addActionListener(e -> scan());
244+
scanButton.addActionListener(e -> scanButtonClicked());
233245

234246
JPanel panel = new JPanel();
235247
GroupLayout layout = new GroupLayout(panel);
@@ -318,31 +330,36 @@ private void reset() {
318330
}
319331
}
320332

321-
private void scan() {
333+
private void scanButtonClicked() {
322334
Optional<File> rootFolder = fileBrowser.browseForRootFolder(jframeProvider.get());
323335
if(rootFolder.isPresent()) {
324-
scanButton.setEnabled(false);
325-
ResolverTask task = new ResolverTask(rootFolder.get());
336+
File root = rootFolder.get();
337+
runResolverTask(Arrays.asList(root));
338+
}
339+
}
340+
341+
private void runResolverTask(List<File> files) {
342+
scanButton.setEnabled(false);
343+
ResolverTask task = new ResolverTask(files);
344+
345+
dialogTaskManager.execute(new TaskIterator(task), new TaskObserver() {
326346

327-
dialogTaskManager.execute(new TaskIterator(task), new TaskObserver() {
328-
329-
@Override
330-
public void taskFinished(ObservableTask task) {
331-
@SuppressWarnings("unchecked")
332-
List<DataSetParameters> datasets = task.getResults(List.class);
333-
if(!datasets.isEmpty()) {
334-
datasets.forEach(MasterDetailDialogPage.this::addDataSetToList);
335-
dataSetList.setSelectedValue(datasets.get(0), true);
336-
}
337-
}
338-
339-
@Override
340-
public void allFinished(FinishStatus finishStatus) {
341-
scanButton.setEnabled(true);
342-
updateButtonEnablement();
347+
@Override
348+
public void taskFinished(ObservableTask task) {
349+
@SuppressWarnings("unchecked")
350+
List<DataSetParameters> datasets = task.getResults(List.class);
351+
if(!datasets.isEmpty()) {
352+
datasets.forEach(MasterDetailDialogPage.this::addDataSetToList);
353+
dataSetList.setSelectedValue(datasets.get(0), true);
343354
}
344-
});
345-
}
355+
}
356+
357+
@Override
358+
public void allFinished(FinishStatus finishStatus) {
359+
scanButton.setEnabled(true);
360+
updateButtonEnablement();
361+
}
362+
});
346363
}
347364

348365

@@ -457,11 +474,18 @@ public DetailPanel getDetailPanel() {
457474

458475
private class DataSetList extends JList<DataSetListItem> {
459476

477+
private boolean isDragging;
478+
460479
@Inject
461480
public DataSetList(ListModel<DataSetListItem> model) {
462481
setModel(model);
463482
setCellRenderer(new CellRenderer());
464483
setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
484+
setDropMode(DropMode.ON);
485+
setTransferHandler(new ResolverTaskTransferHandler());
486+
try {
487+
getDropTarget().addDropTargetListener(getDropTargetListener());
488+
} catch (TooManyListenersException e) { /* do nothing */ }
465489
}
466490

467491
private class CellRenderer implements ListCellRenderer<DataSetListItem> {
@@ -470,8 +494,8 @@ private class CellRenderer implements ListCellRenderer<DataSetListItem> {
470494
public Component getListCellRendererComponent(JList<? extends DataSetListItem> list,
471495
DataSetListItem listItem, int index, boolean isSelected, boolean cellHasFocus) {
472496

473-
Color bgColor = UIManager.getColor(isSelected ? "Table.selectionBackground" : "Table.background");
474-
Color fgColor = UIManager.getColor(isSelected ? "Table.selectionForeground" : "Table.foreground");
497+
Color bgColor = UIManager.getColor(isSelected | isDragging ? "Table.selectionBackground" : "Table.background");
498+
Color fgColor = UIManager.getColor(isSelected ? "Table.selectionForeground" : "Table.foreground");
475499

476500
DetailPanel detail = listItem.getDetailPanel();
477501
JLabel iconLabel = new JLabel(" " + detail.getIcon() + " ");
@@ -486,7 +510,6 @@ public Component getListCellRendererComponent(JList<? extends DataSetListItem> l
486510
JPanel panel = new JPanel(new BorderLayout());
487511
panel.add(iconLabel, BorderLayout.WEST);
488512
panel.add(titleLabel, BorderLayout.CENTER);
489-
490513
panel.setBackground(bgColor);
491514

492515
Border emptyBorder = BorderFactory.createEmptyBorder(2, 4, 2, 4);
@@ -495,6 +518,65 @@ public Component getListCellRendererComponent(JList<? extends DataSetListItem> l
495518
return panel;
496519
}
497520
}
521+
522+
private DropTargetListener getDropTargetListener() {
523+
return new DropTargetAdapter() {
524+
Color normalColor = getBackground();
525+
Color dragColor = UIManager.getColor("Table.selectionBackground");
526+
527+
public void dragEnter(DropTargetDragEvent e) {
528+
isDragging = true;
529+
setBackground(dragColor);
530+
}
531+
public void dragExit(DropTargetEvent e) {
532+
isDragging = false;
533+
setBackground(normalColor);
534+
}
535+
public void drop(DropTargetDropEvent e) {
536+
isDragging = false;
537+
setBackground(normalColor);
538+
}
539+
};
540+
}
541+
}
542+
543+
544+
private class ResolverTaskTransferHandler extends TransferHandler {
545+
546+
@Override
547+
public boolean canImport(TransferSupport support) {
548+
if(!support.isDrop())
549+
return false;
550+
if(!support.isDataFlavorSupported(DataFlavor.javaFileListFlavor))
551+
return false;
552+
boolean copySupported = (COPY & support.getSourceDropActions()) == COPY;
553+
if(!copySupported)
554+
return false;
555+
return true;
556+
}
557+
558+
@Override
559+
public boolean importData(TransferSupport support) {
560+
if(!canImport(support))
561+
return false;
562+
563+
Object transferData;
564+
try {
565+
transferData = support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
566+
} catch (UnsupportedFlavorException | IOException e) {
567+
e.printStackTrace();
568+
return false;
569+
}
570+
571+
if(transferData instanceof List) {
572+
@SuppressWarnings("unchecked")
573+
List<File> fileList = (List<File>) transferData;
574+
runResolverTask(fileList);
575+
return true;
576+
}
577+
return false;
578+
}
579+
498580
}
499581

500582
}

0 commit comments

Comments
 (0)