Skip to content

Commit 788f049

Browse files
Theo Weidmannchhagedorn
Theo Weidmann
authored andcommittedJan 16, 2025
8346607: IGV: Support drag-and-drop for opening graph files
Reviewed-by: rcastanedalo, chagedorn, dfenacci, thartmann
1 parent bfa0cb7 commit 788f049

File tree

2 files changed

+150
-10
lines changed

2 files changed

+150
-10
lines changed
 

‎src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java

+103-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2008, 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -37,8 +37,18 @@
3737
import com.sun.hotspot.igv.settings.Settings;
3838
import com.sun.hotspot.igv.util.LookupHistory;
3939
import com.sun.hotspot.igv.view.EditorTopComponent;
40+
import com.sun.hotspot.igv.view.PlaceholderTopComponent;
4041
import java.awt.BorderLayout;
4142
import java.awt.Dimension;
43+
import java.awt.HeadlessException;
44+
import java.awt.datatransfer.DataFlavor;
45+
import java.awt.datatransfer.UnsupportedFlavorException;
46+
import java.awt.dnd.DnDConstants;
47+
import java.awt.dnd.DropTarget;
48+
import java.awt.dnd.DropTargetDragEvent;
49+
import java.awt.dnd.DropTargetDropEvent;
50+
import java.awt.dnd.DropTargetEvent;
51+
import java.awt.dnd.DropTargetListener;
4252
import java.io.*;
4353
import java.nio.channels.FileChannel;
4454
import java.nio.file.*;
@@ -92,6 +102,9 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
92102
private GraphNode[] selectedGraphs = new GraphNode[0];
93103
private Path documentPath = null;
94104

105+
private final DropTargetListener fileDropListener = new FileDropListener();
106+
private final PlaceholderTopComponent editorPlaceholder = new PlaceholderTopComponent(fileDropListener);
107+
95108
private OutlineTopComponent() {
96109
initComponents();
97110

@@ -100,6 +113,17 @@ private OutlineTopComponent() {
100113
initListView();
101114
initToolbar();
102115
server.startServer();
116+
117+
showEditorPlaceholder();
118+
119+
WindowManager.getDefault().invokeWhenUIReady(() -> {
120+
new DropTarget(WindowManager.getDefault().getMainWindow(), fileDropListener);
121+
});
122+
}
123+
124+
private void showEditorPlaceholder() {
125+
editorPlaceholder.open();
126+
editorPlaceholder.requestActive();
103127
}
104128

105129
public static GraphDocument getDocument() {
@@ -236,6 +260,11 @@ private void documentChanged() {
236260
saveAction.setEnabled(enableButton);
237261
saveAsAction.setEnabled(enableButton);
238262
removeAllAction.setEnabled(enableButton);
263+
if (document.getElements().isEmpty()) {
264+
showEditorPlaceholder();
265+
} else {
266+
editorPlaceholder.close();
267+
}
239268
}
240269

241270
@Override
@@ -372,15 +401,20 @@ public void openFile() {
372401
JFileChooser fc = new JFileChooser(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT));
373402
fc.setFileFilter(graphFileFilter);
374403
if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
375-
clearWorkspace();
376-
String path = fc.getSelectedFile().getAbsolutePath();
377-
Settings.get().put(Settings.DIRECTORY, path);
378-
setDocumentPath(path);
379-
try {
380-
loadGraphDocument(path, true);
381-
} catch (IOException e) {
382-
throw new RuntimeException(e);
383-
}
404+
handleOpen(fc.getSelectedFile());
405+
}
406+
}
407+
408+
private void handleOpen(File file) {
409+
clearWorkspace();
410+
editorPlaceholder.close();
411+
String path = file.getAbsolutePath();
412+
Settings.get().put(Settings.DIRECTORY, path);
413+
setDocumentPath(path);
414+
try {
415+
loadGraphDocument(path, true);
416+
} catch (IOException e) {
417+
throw new RuntimeException(e);
384418
}
385419
}
386420

@@ -590,6 +624,65 @@ public void setState(String state) {
590624
handle.finish();
591625
}
592626

627+
private class FileDropListener implements DropTargetListener {
628+
@Override
629+
public void dragEnter(DropTargetDragEvent dtde) {
630+
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
631+
dtde.acceptDrag(DnDConstants.ACTION_COPY);
632+
} else {
633+
dtde.rejectDrag();
634+
}
635+
}
636+
637+
@Override
638+
public void dragOver(DropTargetDragEvent dtde) {
639+
dragEnter(dtde);
640+
}
641+
642+
@Override
643+
public void dropActionChanged(DropTargetDragEvent dtde) {}
644+
645+
@Override
646+
public void dragExit(DropTargetEvent dte) {}
647+
648+
@Override
649+
public void drop(DropTargetDropEvent dtde) {
650+
try {
651+
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
652+
dtde.acceptDrop(DnDConstants.ACTION_COPY);
653+
654+
List<File> droppedFiles = (List<File>) dtde.getTransferable()
655+
.getTransferData(DataFlavor.javaFileListFlavor);
656+
657+
if (droppedFiles.isEmpty()) return;
658+
if (droppedFiles.size() > 1) {
659+
JOptionPane.showMessageDialog(null,
660+
"Please only drag and drop one file as only one file can be open at a time.",
661+
"Multiple Files Dropped", JOptionPane.WARNING_MESSAGE);
662+
return;
663+
}
664+
665+
File file = droppedFiles.get(0);
666+
667+
if (file.getName().endsWith(".xml") || file.getName().endsWith(".igv")) {
668+
handleOpen(file);
669+
} else {
670+
JOptionPane.showMessageDialog(null,
671+
"Unsupported file type: " + file.getName(),
672+
"Unsupported File", JOptionPane.WARNING_MESSAGE);
673+
}
674+
675+
dtde.dropComplete(true);
676+
} else {
677+
dtde.rejectDrop();
678+
}
679+
} catch (HeadlessException | UnsupportedFlavorException | IOException ex) {
680+
ex.printStackTrace();
681+
dtde.dropComplete(false);
682+
}
683+
}
684+
}
685+
593686
/** This method is called from within the constructor to
594687
* initialize the form.
595688
* WARNING: Do NOT modify this code. The content of this method is
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
package com.sun.hotspot.igv.view;
25+
26+
import java.awt.BorderLayout;
27+
import java.awt.dnd.DropTarget;
28+
import java.awt.dnd.DropTargetListener;
29+
import javax.swing.JLabel;
30+
import javax.swing.JPanel;
31+
import javax.swing.SwingConstants;
32+
import org.openide.windows.TopComponent;
33+
34+
/**
35+
* This TopComponent is displayed in the editor location if no graphs have been loaded
36+
* and allows the user to easily drag and drop graph files to be opened.
37+
*/
38+
public class PlaceholderTopComponent extends TopComponent {
39+
public PlaceholderTopComponent(DropTargetListener fileDropListener) {
40+
setLayout(new BorderLayout());
41+
JPanel container = new JPanel(new BorderLayout());
42+
container.add(new JLabel("Drop file here to open", SwingConstants.CENTER), BorderLayout.CENTER);
43+
container.setDropTarget(new DropTarget(container, fileDropListener));
44+
add(container, BorderLayout.CENTER);
45+
setName("Welcome");
46+
}
47+
}

0 commit comments

Comments
 (0)
Please sign in to comment.