I am new to swing and I am trying to implement drag (export) option to JScrollPane. I have already implemented drop (import) option in my TransferHandler class:
final class FileDropHandler extends TransferHandler {
#Override
public boolean canImport(TransferHandler.TransferSupport support) {
for (DataFlavor flavor : support.getDataFlavors()) {
if (flavor.isFlavorJavaFileListType()) {
return true;
}
}
return false;
}
#Override
#SuppressWarnings("unchecked")
public boolean importData(TransferHandler.TransferSupport support) {
if (!this.canImport(support))
return false;
List<File> files;
try {
files = (List<File>) support.getTransferable()
.getTransferData(DataFlavor.javaFileListFlavor);
} catch (UnsupportedFlavorException | IOException ex) {
// should never happen (or JDK is buggy)
return false;
}
for (File file: files) {
// do something...
}
return true;
}
}
After setting Transfer Handler to JScrollPane, file import works like a charm:
scrollPane.setTransferHandler(new FileDropHandler());
But how can I export files from JScrollPane to desktop or folder? I want to export files.
Take a look at the following question. I don't think it answers your question perfectly but it should give you a good starting point on exporting files.
Swing application -> Drag & drop to the desktop / folder
Here is a modified example from that answer you can run:
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.TransferHandler;
public class DnDFrame extends javax.swing.JFrame implements DropTargetListener {
private DefaultListModel listModel = new DefaultListModel();
private DropTarget dropTarget;
public static void main(String[] args) {
DnDFrame dnd = new DnDFrame();
dnd.setVisible(true);
}
/** Creates new form DnDFrame */
public DnDFrame() {
initComponents();
dropTarget = new DropTarget(list, this);
list.setModel(listModel);
list.setDragEnabled(true);
list.setTransferHandler(new FileTransferHandler());
}
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
jLabel1 = new javax.swing.JLabel();
jScrollPane1 = new javax.swing.JScrollPane();
list = new javax.swing.JList();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new java.awt.GridBagLayout());
jLabel1.setText("Files:");
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
getContentPane().add(jLabel1, gridBagConstraints);
jScrollPane1.setViewportView(list);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
getContentPane().add(jScrollPane1, gridBagConstraints);
pack();
private javax.swing.JLabel jLabel1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JList list;
public void dragEnter(DropTargetDragEvent arg0) {
// nothing
}
public void dragOver(DropTargetDragEvent arg0) {
// nothing
}
public void dropActionChanged(DropTargetDragEvent arg0) {
// nothing
}
public void dragExit(DropTargetEvent arg0) {
// nothing
}
public void drop(DropTargetDropEvent evt) {
int action = evt.getDropAction();
evt.acceptDrop(action);
try {
Transferable data = evt.getTransferable();
if (data.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
List<File> files = (List<File>) data.getTransferData(
DataFlavor.javaFileListFlavor);
for (File file : files) {
listModel.addElement(file);
}
}
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
evt.dropComplete(true);
}
}
private class FileTransferHandler extends TransferHandler {
#Override
protected Transferable createTransferable(JComponent c) {
JList list = (JList) c;
List<File> files = new ArrayList<File>();
for (Object obj: list.getSelectedValues()) {
files.add((File)obj);
}
return new FileTransferable(files);
}
#Override
public int getSourceActions(JComponent c) {
return MOVE;
}
}
private class FileTransferable implements Transferable {
private List<File> files;
public FileTransferable(List<File> files) {
this.files = files;
}
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{DataFlavor.javaFileListFlavor};
}
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(DataFlavor.javaFileListFlavor);
}
public Object getTransferData(DataFlavor flavor)
throws UnsupportedFlavorException, IOException {
if (!isDataFlavorSupported(flavor)) {
throw new UnsupportedFlavorException(flavor);
}
return files;
}
}
}
Related
I have a code in which I must drag two images from my desktop and drop it on a frame in two draggable buttons. The buttons have already been made on the frame. But while dragging the images, they can only be dragged to one button. The images don't get dragged to the other one. I have made a DragListener class where the dragging methods prevail and the main class DragInitialListener where I have passed objects of class DragButton so that two draggable buttons are created. I have tried everything I could think of, made two DragListener classes, passed the methods differently but the image could only be dragged in one button. I want both the buttons to be able to hold images. Please help me with it. Here's the code that I have made so far:
//This is the main class
public class DragInitialListener extends javax.swing.JFrame {
private volatile int draggedAtX, draggedAtY;
public DragInitialListener() {
initComponents();
Droptargets();
Droptarget();
}
public void Droptarget()
{
DragListener d;
DragButton db = new DragButton();
db.setSize(170,140);
d= new DragListener(db);
DropTarget drop = new DropTarget(this,d);
this.getContentPane().add(db);
}
public void Droptargets()
{
DragListener dd;
DragButton db1 = new DragButton();
db1.setSize(170,140);
dd= new DragListener(db1);
DropTarget drop1 = new DropTarget(this,dd);
this.getContentPane().add(db1);
}
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
pack();
}// </editor-fold>
public static void main(String args[]) {
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new DragInitialListener().setVisible(true);
}
});
}
// Variables declaration - do not modify
// End of variables declaration
}
//This is the DragListener class
public class DragListener extends JButton implements DropTargetListener
{
JButton imagebutton = new JButton();
// JButton imagebutton1 = new JButton();
private volatile int draggedAtX, draggedAtY;
DragListener(JButton image) {
imagebutton=image;
}
#Override
public void dragEnter(DropTargetDragEvent dtde) {
}
#Override
public void dragOver(DropTargetDragEvent dtde) {
}
#Override
public void dropActionChanged(DropTargetDragEvent dtde) {
}
#Override
public void dragExit(DropTargetEvent dte) {
}
#Override
public void drop(DropTargetDropEvent ev) {
ev.acceptDrop(DnDConstants.ACTION_COPY);
Transferable t = ev.getTransferable();
//DropTarget test = (DropTarget) ev.getSource();
DataFlavor[] df= t.getTransferDataFlavors();
for(DataFlavor f:df)
{
try
{
if(f.isFlavorJavaFileListType())
{
List<File> files =(List<File>) t.getTransferData(f);
for(File file : files)
{
displayImage(file.getPath());
}
}
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex);
}
}
}
private void displayImage(String path)
{
BufferedImage img = null;
try
{
img =ImageIO.read(new File(path));
}
catch(Exception e)
{
}
ImageIcon icon = new ImageIcon(img);
imagebutton.setIcon(icon);
}
}
Start simple, get one button to work, if you can get one to work, you can get 100 to work
This is a very simple example, which makes use of the transfer API, because you really only care about dropping and not dragging
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.File;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JButton btn = new JButton("Drop here");
btn.setVerticalTextPosition(JButton.BOTTOM);
btn.setHorizontalTextPosition(JButton.CENTER);
btn.setTransferHandler(new ImageTransferHandler());
add(btn);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
public static class ImageTransferHandler extends TransferHandler {
public static final DataFlavor[] SUPPORTED_DATA_FLAVORS = new DataFlavor[]{
DataFlavor.javaFileListFlavor,
DataFlavor.imageFlavor
};
#Override
public boolean canImport(TransferHandler.TransferSupport support) {
boolean canImport = false;
for (DataFlavor flavor : SUPPORTED_DATA_FLAVORS) {
if (support.isDataFlavorSupported(flavor)) {
canImport = true;
break;
}
}
return canImport;
}
#Override
public boolean importData(TransferHandler.TransferSupport support) {
boolean accept = false;
if (canImport(support)) {
try {
Transferable t = support.getTransferable();
Component component = support.getComponent();
if (component instanceof JButton) {
Image image = null;
if (support.isDataFlavorSupported(DataFlavor.imageFlavor)) {
image = (Image) t.getTransferData(DataFlavor.imageFlavor);
} else if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
List files = (List) t.getTransferData(DataFlavor.javaFileListFlavor);
if (files.size() > 0) {
image = ImageIO.read((File) files.get(0));
}
}
ImageIcon icon = null;
if (image != null) {
icon = new ImageIcon(image);
}
((JButton) component).setIcon(icon);
accept = true;
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
return accept;
}
}
}
So, by doing nothing more then changing the layout and replicating the button using
public TestPane() {
setLayout(new GridLayout(5, 5));
for (int index = 0; index < 5 * 5; index++) {
JButton btn = new JButton("Drop here");
btn.setVerticalTextPosition(JButton.BOTTOM);
btn.setHorizontalTextPosition(JButton.CENTER);
btn.setTransferHandler(new ImageTransferHandler());
add(btn);
}
}
I was able to achieve...
Updated...
So apparently I might have misunderstood the question, not the first time. From what's been explained to me, you might want to drag multiple images and have them applied to the buttons. Surprising, the process doesn't change that much.
In this example, I've applied the TransferHandler to the JPanel instead of the button and supplied it the buttons I want updated. You could easily update this to have a variable number of buttons, but I've started with two.
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.File;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.TransferHandler;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JButton left = makeButton("Left");
JButton right = makeButton("Right");
add(left);
add(right);
setTransferHandler(new ImageTransferHandler(left, right));
}
protected JButton makeButton(String text) {
JButton btn = new JButton(text);
btn.setVerticalTextPosition(JButton.BOTTOM);
btn.setHorizontalTextPosition(JButton.CENTER);
return btn;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
public static class ImageTransferHandler extends TransferHandler {
public static final DataFlavor[] SUPPORTED_DATA_FLAVORS = new DataFlavor[]{
DataFlavor.javaFileListFlavor,};
private JButton left, right;
public ImageTransferHandler(JButton left, JButton right) {
this.left = left;
this.right = right;
}
#Override
public boolean canImport(TransferHandler.TransferSupport support) {
boolean canImport = false;
for (DataFlavor flavor : SUPPORTED_DATA_FLAVORS) {
if (support.isDataFlavorSupported(flavor)) {
canImport = true;
break;
}
}
return canImport;
}
#Override
public boolean importData(TransferHandler.TransferSupport support) {
boolean accept = false;
if (canImport(support)) {
try {
Transferable t = support.getTransferable();
Image image = null;
if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
List files = (List) t.getTransferData(DataFlavor.javaFileListFlavor);
JButton buttons[] = new JButton[]{left, right};
for (int index = 0; index < Math.min(files.size(), 2); index++) {
if (files.size() > 0) {
image = ImageIO.read((File) files.get(index));
ImageIcon icon = null;
if (image != null) {
icon = new ImageIcon(image);
}
buttons[index].setIcon(icon);
}
}
accept = true;
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
return accept;
}
}
}
Now, there are rules you will need to define yourself, for example, what happens when the user only drags a single image? Do you apply it to the first button (as I have) every time, or do you try and find the button without an image and update it? What happens if all the buttons have images? Where does it go then?
Do you reject drags with more than 2 images?
I am implementing a functionality to Drag and Drop the Textattribute of JLabels into the cells of a JTable. So I've created a custom TransferHandler for the table.
But every call of
support.isDataFlavorSupported(DataFlavor.stringFlavor)
returns false
How can I make sure that my TransferHandler is able to import Strings?
Here is the source
public class TableHandler extends TransferHandler {
private static final long serialVersionUID = 1L;
#Override
public boolean canImport(TransferSupport support) {
if (!support.isDrop()) {
return false;
}
//only Strings
if(!support.isDataFlavorSupported(DataFlavor.stringFlavor)){
return false;
}
return true;
}
#Override
public boolean importData(TransferSupport support) {
if (!canImport(support)) {
return false;
}
Transferable tansferable = support.getTransferable();
String line;
try {
line = (String) tansferable
.getTransferData(DataFlavor.stringFlavor);
} catch (Exception e) {
return false;
}
JTable.DropLocation dl = (JTable.DropLocation) support
.getDropLocation();
int column = dl.getColumn();
int row = dl.getRow();
String[] data = line.split(",");
for (String item : data) {
if (!item.isEmpty()) {
table.getTableModel().setValueAt(item, row, column);
}
}
return true;
}
}
Check this example seems to work fine:
Before any dragging / dropping of JLabels:
Clicked and dragged Hello JLabel to 1st cell:
On release of click over the first cell:
import java.awt.BorderLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.io.IOException;
import javax.swing.DropMode;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
public class Test {
public static void main(String[] args) {
createAndShowJFrame();
}
public static void createAndShowJFrame() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = createJFrame();
frame.setVisible(true);
}
});
}
private static JFrame createJFrame() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("Test");
JTable table = createJTable();
JScrollPane js = new JScrollPane(table);
frame.add(js, BorderLayout.CENTER);
frame.add(createJLabelPanel(), BorderLayout.SOUTH);
frame.pack();
//frame.setResizable(false);//make it un-resizeable
//frame.setLocationRelativeTo(null);//center JFrame
return frame;
}
private static JTable createJTable() {
// setup table data
String[] columns = new String[]{"Foo", "Bar", "Baz", "Quux"};
String[][] data = new String[][]{{"A", "B", "C", "D"},
{"1", "2", "3", "4"},
{"i", "ii", "iii", "iv"}};
// create table
final JTable table = new JTable(data, columns);
// set up drag and drop
table.setDragEnabled(true);
table.setDropMode(DropMode.USE_SELECTION);
table.setFillsViewportHeight(true);
TransferHandler dnd = new TransferHandler() {
#Override
public boolean canImport(TransferSupport support) {
if (!support.isDrop()) {
return false;
}
//only Strings
if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) {
return false;
}
return true;
}
#Override
public boolean importData(TransferSupport support) {
if (!canImport(support)) {
return false;
}
Transferable tansferable = support.getTransferable();
String line;
try {
line = (String) tansferable.getTransferData(DataFlavor.stringFlavor);
} catch (Exception e) {
e.printStackTrace();
return false;
}
JTable.DropLocation dl = (JTable.DropLocation) support.getDropLocation();
int column = dl.getColumn();
int row = dl.getRow();
String[] data = line.split(",");
for (String item : data) {
if (!item.isEmpty()) {
table.getModel().setValueAt(item, row, column);
}
}
return true;
}
};
table.setTransferHandler(dnd);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
return table;
}
private static JPanel createJLabelPanel() {
JPanel panel = new JPanel();
JLabel label1 = new JLabel("Hello");
JLabel label2 = new JLabel("Yay");
JLabel label3 = new JLabel("Bye");
MyDragGestureListener dlistener = new MyDragGestureListener();
DragSource ds1 = new DragSource();
ds1.createDefaultDragGestureRecognizer(label1, DnDConstants.ACTION_COPY, dlistener);
DragSource ds2 = new DragSource();
ds2.createDefaultDragGestureRecognizer(label2, DnDConstants.ACTION_COPY, dlistener);
DragSource ds3 = new DragSource();
ds3.createDefaultDragGestureRecognizer(label3, DnDConstants.ACTION_COPY, dlistener);
panel.add(label1);
panel.add(label2);
panel.add(label3);
return panel;
}
}
class MyDragGestureListener implements DragGestureListener {
#Override
public void dragGestureRecognized(DragGestureEvent event) {
JLabel label = (JLabel) event.getComponent();
final String text = label.getText();
Transferable transferable = new Transferable() {
#Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{DataFlavor.stringFlavor};
}
#Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
if (!isDataFlavorSupported(flavor)) {
return false;
}
return true;
}
#Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
return text;
}
};
event.startDrag(null, transferable);
}
}
An higher-level alternative to David's low-level approach (for the drag off the label), is to use the in-build property transfer on it. It's installed by simply setting the transferHandler and a mouseListener which triggers the export:
MouseListener listener = new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
JComponent c = (JComponent) e.getSource();
TransferHandler handler = c.getTransferHandler();
handler.exportAsDrag(c, e, TransferHandler.COPY);
}
};
// a transferHandler configured to export the text property
TransferHandler handler = new TransferHandler("text");
JComponent labels = new JPanel();
for (int i = 0; i < 4; i++) {
JLabel label1 = new JLabel("item: " + i);
label1.addMouseListener(listener);
label1.setTransferHandler(handler);
labels.add(label1);
}
The price to pay is slightly more work in the TableTransferHandler: it now has to check not only against the pre-defined stringFlavor but check the representationClass against String and accept that as well:
public class TableHandlerExt extends TransferHandler {
/**
* Implemented to return true if the support can provide string values.
*/
#Override
public boolean canImport(TransferSupport support) {
if (!support.isDrop()) {
return false;
}
return isStringDataSupported(support);
}
/**
* Returns a boolean indicating whether or not the support can
* provide a string value. Checks for predefined DataFlavor.stringFlavor
* and flavors with a representationClass of String.
*/
protected boolean isStringDataSupported(TransferSupport support) {
if (support.isDataFlavorSupported(DataFlavor.stringFlavor)) return true;
DataFlavor[] flavors = support.getDataFlavors();
for (DataFlavor dataFlavor : flavors) {
if (dataFlavor.getRepresentationClass() == String.class) return true;
}
return false;
}
#Override
public boolean importData(TransferSupport support) {
if (!canImport(support)) {
return false;
}
String line;
try {
line = getStringData(support);
} catch (Exception e) {
e.printStackTrace();
return false;
}
JTable table = (JTable) support.getComponent();
JTable.DropLocation dl = (JTable.DropLocation) support.getDropLocation();
int column = dl.getColumn();
int row = dl.getRow();
if (!line.isEmpty()) {
// note: we need to use table api to access the table, as the
// row/column coordinates are view coordinates
table.setValueAt(line, row, column);
}
return true;
}
/**
* Returns the String provided by the support.
* Tries for predefined DataFlavor.stringFlavor
* and flavors with a representationClass of String.
*/
protected String getStringData(TransferSupport support)
throws UnsupportedFlavorException, IOException {
if (support.isDataFlavorSupported(DataFlavor.stringFlavor)) {
return (String) support.getTransferable().getTransferData(DataFlavor.stringFlavor);
}
DataFlavor[] flavors = support.getDataFlavors();
for (DataFlavor dataFlavor : flavors) {
if (dataFlavor.getRepresentationClass() == String.class) {
return (String) support.getTransferable().getTransferData(dataFlavor);
}
}
return "";
}
}
I'm working on Drag & Drop support for a JList component and I would like to be able to support files dragged in from my file browser. I however only want to allow files and not folders to be dragged in. Thus I'm trying to check for it in my TransferHandler like this:
#Override
public boolean canImport(TransferSupport support) {
if (support.getComponent().equals(this.resourceFileList)) {
if (!support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
} else {
try {
// get file list
Transferable transferable = support.getTransferable();
Object transferData = transferable.getTransferData(DataFlavor.javaFileListFlavor);
// check for folders
boolean containsFiles = false;
List files = (List) transferData;
for (int i = 0; i < files.size(); i++) {
File file = (File) files.get(i);
if (!file.isDirectory()) {
containsFiles = true;
}
}
// return file indicator
return containsFiles;
} catch (IOException | UnsupportedFlavorException e) {
System.out.println("Unable to check for folders due to the following exception:\n" + e);
return false;
}
}
} else {
return false;
}
}
Unfortunately transferData seems to be null here. It is however not when the TransferHandler's importData method gets called. Does anyone have any clue if this is a bug of some sorts or desired behaviour?
I'm on a Mac (OSX 10.8) if it makes a difference and Java version is 1.7.0_21.
Thanks in advance!
EDIT:
Here's a short SSCCE for anyone to test. Just a drag a file into the list and watch the console.
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.TransferHandler;
import javax.swing.TransferHandler.TransferSupport;
public class DNDIssue extends TransferHandler {
#Override
public boolean canImport(TransferSupport support) {
if (support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
try {
Transferable transferable = support.getTransferable();
Object transferData = transferable.getTransferData(DataFlavor.javaFileListFlavor); // <-- this returns null
System.out.println(transferData); // null
} catch (IOException | UnsupportedFlavorException e) {
System.out.println("Unable to check for folders due to the following exception:\n" + e);
} finally {
return false;
}
} else {
return false;
}
}
public static void main(String[] args) {
// create window
JFrame window = new JFrame("DNDIssue");
window.setSize(640, 480);
window.setLocation(100, 100);
// create list with model and set transfer handler
JList<File> list = new JList<File>(new DefaultListModel<File>());
list.setTransferHandler(new DNDIssue());
// add enclosing scroll pane and display window
window.getContentPane().add(new JScrollPane(list));
window.setVisible(true);
}
}
Your SSCCE works fine for me using JDK 1.7.0_21 on Windows 7 64bit.
Could you try following code?
Transferable transferable = support.getTransferable();
System.out.println("----");
String mt = DataFlavor.javaFileListFlavor.getMimeType();
for(DataFlavor df: transferable.getTransferDataFlavors()) {
System.out.println(df.getMimeType());
System.out.println(" "+df.getMimeType().equals(mt));
}
SSCCE 1.0: delete
SSCCE 1.1: Override TransferHandler#importData(...) version
InvalidDnDOperationException: No drop current
java.awt.dnd.InvalidDnDOperationException: No drop current
at sun.awt.dnd.SunDropTargetContextPeer.getTransferData(SunDropTargetContextPeer.java:245)
at sun.awt.datatransfer.TransferableProxy.getTransferData(TransferableProxy.java:73)
at java.awt.dnd.DropTargetContext$TransferableProxy.getTransferData(DropTargetContext.java:376)
at FileTransferHandler.canImport(DNDIssueTest.java:64)
The problem is possibly related to Bug ID 6759788 http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6759788
via: http://www.coderanch.com/t/466319/GUI/java/Drag-Drop
SSCCE 1.2: Ignore InvalidDnDOperationException
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.io.*;
import java.util.List;
import javax.swing.*;
import javax.swing.TransferHandler;
import javax.swing.TransferHandler.TransferSupport;
public class DNDIssueTest {
public JComponent makeUI() {
// create list with model and set transfer handler
JList<File> list = new JList<File>(new DefaultListModel<File>());
list.setDropMode(DropMode.INSERT);
list.setTransferHandler(new FileTransferHandler());
return new JScrollPane(list);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new DNDIssueTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class FileTransferHandler extends TransferHandler {
private static final boolean DEBUG = true;
#SuppressWarnings("unchecked")
#Override public boolean importData(TransferSupport support) {
try {
List files = (List)support.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
System.out.println("importData");
if(!hasDirectory(files) && canImport(support)) {
JList list = (JList)support.getComponent();
DefaultListModel model = (DefaultListModel)list.getModel();
for(Object o: files) {
model.addElement(o);
}
return true;
}
} catch(Exception ex) {
ex.printStackTrace();
}
return false;
}
private boolean hasDirectory(List list) {
System.out.println("hasDirectory check");
for (Object o: list) {
if(o instanceof File) {
File file = (File) o;
if (file.isDirectory()) {
return true;
}
}
}
return false;
}
#Override public boolean canImport(TransferSupport support) {
if(!support.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
return false;
}
if(!DEBUG) return true;
Transferable transferable = support.getTransferable();
try {
Object transferData = transferable.getTransferData(DataFlavor.javaFileListFlavor);
//System.out.println(transferData); // null
System.out.println("canImport");
return !hasDirectory((List)transferData);
} catch (Exception e) {
//e.printStackTrace();
System.out.println("*** Ignore InvalidDnDOperationException ***");
return true;
}
}
}
SSCCE 2.0: DropTargetListener version
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.event.*;
import java.io.*;
import java.util.List;
import javax.swing.*;
public class DNDIssueTest2 {
public JComponent makeUI() {
final DefaultListModel<File> model = new DefaultListModel<>();
JList<File> list = new JList<File>(model);
DropTargetListener dtl = new DropTargetAdapter() {
#Override public void dragOver(DropTargetDragEvent dtde) {
if(dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
Transferable transferable = dtde.getTransferable();
Object transferData = null;
try {
transferData = transferable.getTransferData(DataFlavor.javaFileListFlavor);
} catch(Exception ex) {
dtde.rejectDrag();
return;
}
List<File> files = (List<File>)transferData;
for (int i = 0; i < files.size(); i++) {
File file = (File) files.get(i);
if (file.isDirectory()) {
dtde.rejectDrag();
return;
}
}
dtde.acceptDrag(DnDConstants.ACTION_COPY);
return;
}
dtde.rejectDrag();
}
#Override public void drop(DropTargetDropEvent dtde) {
try {
if(dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrop(DnDConstants.ACTION_COPY);
Transferable transferable = dtde.getTransferable();
List list = (List)transferable.getTransferData(DataFlavor.javaFileListFlavor);
for(Object o: list) {
if(o instanceof File) {
File file = (File) o;
model.addElement(file);
}
}
dtde.dropComplete(true);
return;
}
} catch(UnsupportedFlavorException ufe) {
ufe.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
}
dtde.rejectDrop();
}
};
new DropTarget(list, DnDConstants.ACTION_COPY, dtl, true);
return new JScrollPane(list);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new DNDIssueTest2().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
I want to implement dragging and dropping of files from a directory such as someones hard drive but can't figure out how to do it. I've read the java api but it talks of color pickers and dragging and dropping between lists but how to drag files from a computers file system and drop into my application. I tried writing the transferhandler class and a mouse event for when the drag starts but nothing seems to work. Now I'm back to just having my JFileChooser set so drag has been enabled but how to drop?
Any info or point in the right direction greatly appreciated.
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileFilter;
public class FileChooserDemo
extends JPanel
implements ActionListener
{
JLabel selectedFileLabel;
JList selectedFilesList;
JLabel returnCodeLabel;
public FileChooserDemo()
{
super();
createContent();
}
void initFrameContent()
{
JPanel closePanel = new JPanel();
add(closePanel, BorderLayout.SOUTH);
}
private void createContent()
{
setLayout(new BorderLayout());
JPanel NorthPanel = new JPanel();
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("File");
JMenuItem quit = new JMenuItem("Quit");
menuBar.add(menu);
menu.add(quit);
NorthPanel.add(menu,BorderLayout.NORTH);
JPanel buttonPanel = new JPanel(new GridLayout(7,1 ));
JButton openButton = new JButton("Open...");
openButton.setActionCommand("OPEN");
openButton.addActionListener(this);
buttonPanel.add(openButton);
JButton saveButton = new JButton("Save...");
saveButton.setActionCommand("SAVE");
saveButton.addActionListener(this);
buttonPanel.add(saveButton);
JButton delete = new JButton("Delete");
delete.addActionListener(this);
delete.setActionCommand("DELETE");
buttonPanel.add(delete);
add(buttonPanel, BorderLayout.WEST);
// create a panel to display the selected file(s) and the return code
JPanel displayPanel = new JPanel(new BorderLayout());
selectedFileLabel = new JLabel("-");
selectedFileLabel.setBorder(BorderFactory.createTitledBorder
("Selected File/Directory "));
displayPanel.add(selectedFileLabel, BorderLayout.NORTH);
selectedFilesList = new JList();
JScrollPane sp = new JScrollPane(selectedFilesList);
sp.setBorder(BorderFactory.createTitledBorder("Selected Files "));
MouseListener listener = new MouseAdapter()
{
public void mousePressed(MouseEvent me)
{
JComponent comp = (JComponent) me.getSource();
TransferHandler handler = comp.getTransferHandler();
handler.exportAsDrag(comp, me, TransferHandler.MOVE);
}
};
selectedFilesList.addMouseListener(listener);
displayPanel.add(sp);
returnCodeLabel = new JLabel("");
returnCodeLabel.setBorder(BorderFactory.createTitledBorder("Return Code"));
displayPanel.add(returnCodeLabel, BorderLayout.SOUTH);
add(displayPanel);
}
public void actionPerformed(ActionEvent e)
{
int option = 0;
File selectedFile = null;
File[] selectedFiles = new File[0];
if (e.getActionCommand().equals("CLOSE"))
{
System.exit(0);
}
else if (e.getActionCommand().equals("OPEN"))
{
JFileChooser chooser = new JFileChooser();
chooser.setDragEnabled(true);
chooser.setMultiSelectionEnabled(true);
option = chooser.showOpenDialog(this);
selectedFiles = chooser.getSelectedFiles();
}
else if (e.getActionCommand().equals("SAVE"))
{
JFileChooser chooser = new JFileChooser();
option = chooser.showSaveDialog(this);
selectedFiles = chooser.getSelectedFiles();
}
// display the selection and return code
if (selectedFile != null)
selectedFileLabel.setText(selectedFile.toString());
else
selectedFileLabel.setText("null");
DefaultListModel listModel = new DefaultListModel();
for (int i =0; i < selectedFiles.length; i++)
listModel.addElement(selectedFiles[i]);
selectedFilesList.setModel(listModel);
returnCodeLabel.setText(Integer.toString(option));
}
public static void main(String[] args)
{
SwingUtilities.invokeLater
(new Runnable()
{
public void run()
{
FileChooserDemo app = new FileChooserDemo();
app.initFrameContent();
JFrame frame = new JFrame("LoquetUP");
frame.getContentPane().add(app);
frame.setDefaultCloseOperation(3);
frame.setSize(600,400);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
//frame.pack();
frame.setVisible(true);
}
});
}
}
This is my take on the idea. I've used the "traditional" drag and drop API in this example. It has some extra "paint" tweaks just to show off what you might be able to do.
This example doesn't scan folders dropped onto it, so any folder will only register as a single file, but I'm sure you can work it out
public class TestDragNDropFiles {
public static void main(String[] args) {
new TestDragNDropFiles();
}
public TestDragNDropFiles() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DropPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class DropPane extends JPanel {
private DropTarget dropTarget;
private DropTargetHandler dropTargetHandler;
private Point dragPoint;
private boolean dragOver = false;
private BufferedImage target;
private JLabel message;
public DropPane() {
try {
target = ImageIO.read(new File("target.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
setLayout(new GridBagLayout());
message = new JLabel();
message.setFont(message.getFont().deriveFont(Font.BOLD, 24));
add(message);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
protected DropTarget getMyDropTarget() {
if (dropTarget == null) {
dropTarget = new DropTarget(this, DnDConstants.ACTION_COPY_OR_MOVE, null);
}
return dropTarget;
}
protected DropTargetHandler getDropTargetHandler() {
if (dropTargetHandler == null) {
dropTargetHandler = new DropTargetHandler();
}
return dropTargetHandler;
}
#Override
public void addNotify() {
super.addNotify();
try {
getMyDropTarget().addDropTargetListener(getDropTargetHandler());
} catch (TooManyListenersException ex) {
ex.printStackTrace();
}
}
#Override
public void removeNotify() {
super.removeNotify();
getMyDropTarget().removeDropTargetListener(getDropTargetHandler());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (dragOver) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(new Color(0, 255, 0, 64));
g2d.fill(new Rectangle(getWidth(), getHeight()));
if (dragPoint != null && target != null) {
int x = dragPoint.x - 12;
int y = dragPoint.y - 12;
g2d.drawImage(target, x, y, this);
}
g2d.dispose();
}
}
protected void importFiles(final List files) {
Runnable run = new Runnable() {
#Override
public void run() {
message.setText("You dropped " + files.size() + " files");
}
};
SwingUtilities.invokeLater(run);
}
protected class DropTargetHandler implements DropTargetListener {
protected void processDrag(DropTargetDragEvent dtde) {
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrag(DnDConstants.ACTION_COPY);
} else {
dtde.rejectDrag();
}
}
#Override
public void dragEnter(DropTargetDragEvent dtde) {
processDrag(dtde);
SwingUtilities.invokeLater(new DragUpdate(true, dtde.getLocation()));
repaint();
}
#Override
public void dragOver(DropTargetDragEvent dtde) {
processDrag(dtde);
SwingUtilities.invokeLater(new DragUpdate(true, dtde.getLocation()));
repaint();
}
#Override
public void dropActionChanged(DropTargetDragEvent dtde) {
}
#Override
public void dragExit(DropTargetEvent dte) {
SwingUtilities.invokeLater(new DragUpdate(false, null));
repaint();
}
#Override
public void drop(DropTargetDropEvent dtde) {
SwingUtilities.invokeLater(new DragUpdate(false, null));
Transferable transferable = dtde.getTransferable();
if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
dtde.acceptDrop(dtde.getDropAction());
try {
List transferData = (List) transferable.getTransferData(DataFlavor.javaFileListFlavor);
if (transferData != null && transferData.size() > 0) {
importFiles(transferData);
dtde.dropComplete(true);
}
} catch (Exception ex) {
ex.printStackTrace();
}
} else {
dtde.rejectDrop();
}
}
}
public class DragUpdate implements Runnable {
private boolean dragOver;
private Point dragPoint;
public DragUpdate(boolean dragOver, Point dragPoint) {
this.dragOver = dragOver;
this.dragPoint = dragPoint;
}
#Override
public void run() {
DropPane.this.dragOver = dragOver;
DropPane.this.dragPoint = dragPoint;
DropPane.this.repaint();
}
}
}
}
You need to experiment with Drag & Drop and see exactly what flavors are available when you try to drag files. If you do this in your custom TransferHandler you'll be pleasantly surprised one Flavor is the DataFlavor.javaFileListFlavor, which indicates that the item can be used simply as a List. Try it and you'll see that it works!
Note on review of your posted code, I don't see any code for your attempt at using a TransferHandler, so it is hard to say what you could be doing wrong here.
Edit 1
You seem to be trying to use a MouseListener for your drag and drop, and I'm not familiar with this usage. Can you show a reference to a tutorial that tells you to do this?
Edit 2
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class FileDragDemo extends JPanel {
private JList list = new JList();
public FileDragDemo() {
list.setDragEnabled(true);
list.setTransferHandler(new FileListTransferHandler(list));
add(new JScrollPane(list));
}
private static void createAndShowGui() {
FileDragDemo mainPanel = new FileDragDemo();
JFrame frame = new JFrame("FileDragDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
#SuppressWarnings("serial")
class FileListTransferHandler extends TransferHandler {
private JList list;
public FileListTransferHandler(JList list) {
this.list = list;
}
public int getSourceActions(JComponent c) {
return COPY_OR_MOVE;
}
public boolean canImport(TransferSupport ts) {
return ts.isDataFlavorSupported(DataFlavor.javaFileListFlavor);
}
public boolean importData(TransferSupport ts) {
try {
#SuppressWarnings("rawtypes")
List data = (List) ts.getTransferable().getTransferData(
DataFlavor.javaFileListFlavor);
if (data.size() < 1) {
return false;
}
DefaultListModel listModel = new DefaultListModel();
for (Object item : data) {
File file = (File) item;
listModel.addElement(file);
}
list.setModel(listModel);
return true;
} catch (UnsupportedFlavorException e) {
return false;
} catch (IOException e) {
return false;
}
}
}
I have this code want to make JList talk text and icon what must to do.
Some persons advice me to make list of label and in table put text an icon is it Possible? How?
Search on ///////////////// for embedded comment.
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetDragEvent;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.dnd.DropTargetEvent;
import java.awt.dnd.DropTargetListener;
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.filechooser.FileSystemView;
public class pan extends JPanel implements DropTargetListener {
private DefaultListModel listModel = new DefaultListModel();
private DropTarget dropTarget;
private JLabel jLabel1;
private JScrollPane jScrollPane1;
private JList list;
/**
* Create the panel.
*/
public pan() {
setLayout(null);
list = new JList();
dropTarget = new DropTarget(list, this);
list.setModel(listModel);
list.setDragEnabled(true);
//list.setTransferHandler(new FileTransferHandler());
jScrollPane1 = new JScrollPane();
jScrollPane1.setViewportView(list);
jScrollPane1.setBounds(10, 150, 635, 330);
add(jScrollPane1);
}
public void dragEnter(DropTargetDragEvent arg0) {
// nothing
}
public void dragOver(DropTargetDragEvent arg0) {
// nothing
}
public void dropActionChanged(DropTargetDragEvent arg0) {
// nothing
}
public void dragExit(DropTargetEvent arg0) {
// nothing
}
public void drop(DropTargetDropEvent evt) {
int action = evt.getDropAction();
evt.acceptDrop(action);
try {
Transferable data = evt.getTransferable();
if (data.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
List<File> files = (List<File>) data.getTransferDat(DataFlavor.javaFileListFlavor);
for (File file : files) {
Icon icon=FileSystemView.getFileSystemView().getSystemIcon(file);
/////////////////listModel.addElement(filepath+icon);///////////////////////want code do this
}
}
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
evt.dropComplete(true);
}
}
}
After solve this problem i will add action to each element if doubel click on it will open desktop
to path stored in list.
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.filechooser.FileSystemView;
import java.io.*;
import java.util.List;
public class FileDropList extends JPanel implements DropTargetListener {
private DefaultListModel listModel = new DefaultListModel();
private DropTarget dropTarget;
private JLabel jLabel1;
private JScrollPane jScrollPane1;
private JList list;
/**
* Create the panel.
*/
public FileDropList() {
//setLayout(null);
list = new JList();
dropTarget = new DropTarget(list, this);
list.setModel(listModel);
list.setDragEnabled(true);
FileListCellRenderer renderer = new FileListCellRenderer();
list.setCellRenderer(renderer);
//list.setTransferHandler(new FileTransferHandler());
jScrollPane1 = new JScrollPane(list);
//jScrollPane1.setBounds(10, 150, 635, 330);
add(jScrollPane1);
}
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
#Override
public void run() {
JPanel pan = new FileDropList();
pan.setBorder(new LineBorder(Color.BLACK));
JOptionPane.showMessageDialog(null, pan);
}
};
SwingUtilities.invokeLater(r);
}
public void dragEnter(DropTargetDragEvent arg0) {
// nothing
}
public void dragOver(DropTargetDragEvent arg0) {
// nothing
}
public void dropActionChanged(DropTargetDragEvent arg0) {
// nothing
}
public void dragExit(DropTargetEvent arg0) {
// nothing
}
public void drop(DropTargetDropEvent evt) {
int action = evt.getDropAction();
evt.acceptDrop(action);
try {
Transferable data = evt.getTransferable();
if (data.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
List<File> files = (List<File>) data.getTransferData(DataFlavor.javaFileListFlavor);
for (File file : files) {
listModel.addElement(file);
}
}
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
evt.dropComplete(true);
}
}
}
/** A FileListCellRenderer for a File. */
class FileListCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = -7799441088157759804L;
private FileSystemView fileSystemView;
private JLabel label;
private Color textSelectionColor = Color.BLACK;
private Color backgroundSelectionColor = Color.CYAN;
private Color textNonSelectionColor = Color.BLACK;
private Color backgroundNonSelectionColor = Color.WHITE;
FileListCellRenderer() {
label = new JLabel();
label.setOpaque(true);
fileSystemView = FileSystemView.getFileSystemView();
}
#Override
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean selected,
boolean expanded) {
File file = (File)value;
label.setIcon(fileSystemView.getSystemIcon(file));
label.setText(fileSystemView.getSystemDisplayName(file));
label.setToolTipText(file.getPath());
if (selected) {
label.setBackground(backgroundSelectionColor);
label.setForeground(textSelectionColor);
} else {
label.setBackground(backgroundNonSelectionColor);
label.setForeground(textNonSelectionColor);
}
return label;
}
}
Original Answer
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import java.io.*;
import java.util.List;
public class FileDragList extends JPanel implements DropTargetListener {
private static final long serialVersionUID = 1L;
private DefaultListModel listModel = new DefaultListModel();
private JScrollPane jScrollPane1;
private JList list;
/**
* Create the panel.
*/
public FileDragList() {
setLayout(null);
list = new JList();
DropTarget dropTarget = new DropTarget(list, this);
list.setModel(listModel);
list.setDragEnabled(true);
FileListCellRenderer renderer = new FileListCellRenderer();
list.setCellRenderer(renderer);
//list.setTransferHandler(new FileTransferHandler());
jScrollPane1 = new JScrollPane();
jScrollPane1.setViewportView(list);
jScrollPane1.setBounds(10, 150, 635, 330);
add(jScrollPane1);
}
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
#Override
public void run() {
JOptionPane.showMessageDialog(null, new FileDragList());
}
};
SwingUtilities.invokeLater(r);
}
public void dragEnter(DropTargetDragEvent arg0) {
// nothing
}
public void dragOver(DropTargetDragEvent arg0) {
// nothing
}
public void dropActionChanged(DropTargetDragEvent arg0) {
// nothing
}
public void dragExit(DropTargetEvent arg0) {
// nothing
}
public void drop(DropTargetDropEvent evt) {
int action = evt.getDropAction();
evt.acceptDrop(action);
try {
Transferable data = evt.getTransferable();
if (data.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
List<File> files = (List<File>) data.getTransferData(DataFlavor.javaFileListFlavor);
for (File file : files) {
Icon icon=FileSystemView.getFileSystemView().getSystemIcon(file);
/////////////////listModel.addElement(filepath+icon);///////////////////////want code do this
}
}
} catch (UnsupportedFlavorException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
evt.dropComplete(true);
}
}
}
Icon icon=FileSystemView.getFileSystemView().getSystemIcon(file);
Oh right.. Try a variant of the FileTreeCellRenderer of File Browser GUI.
That's it, used for the tree on the left.
FileTreeCellRenderer
/** A TreeCellRenderer for a File. */
class FileTreeCellRenderer extends DefaultTreeCellRenderer {
private FileSystemView fileSystemView;
private JLabel label;
FileTreeCellRenderer() {
label = new JLabel();
label.setOpaque(true);
fileSystemView = FileSystemView.getFileSystemView();
}
#Override
public Component getTreeCellRendererComponent(
JTree tree,
Object value,
boolean selected,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
File file = (File)node.getUserObject();
label.setIcon(fileSystemView.getSystemIcon(file));
label.setText(fileSystemView.getSystemDisplayName(file));
label.setToolTipText(file.getPath());
if (selected) {
label.setBackground(backgroundSelectionColor);
label.setForeground(textSelectionColor);
} else {
label.setBackground(backgroundNonSelectionColor);
label.setForeground(textNonSelectionColor);
}
return label;
}
}
Update
An SSCCE that adapts the renderer above for lists.
import java.awt.*;
import javax.swing.*;
import javax.swing.filechooser.FileSystemView;
import java.io.File;
public class FileList {
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
#Override
public void run() {
JPanel gui = new JPanel(new BorderLayout(2,2));
File userHome = new File(System.getProperty("user.home"));
File[] files = userHome.listFiles();
JList list = new JList(files);
list.setCellRenderer(new FileListCellRenderer());
gui.add(new JScrollPane(list));
JOptionPane.showMessageDialog(null, gui);
}
};
SwingUtilities.invokeLater(r);
}
}
/** A FileListCellRenderer for a File. */
class FileListCellRenderer extends DefaultListCellRenderer {
private static final long serialVersionUID = -7799441088157759804L;
private FileSystemView fileSystemView;
private JLabel label;
private Color textSelectionColor = Color.BLACK;
private Color backgroundSelectionColor = Color.CYAN;
private Color textNonSelectionColor = Color.BLACK;
private Color backgroundNonSelectionColor = Color.WHITE;
FileListCellRenderer() {
label = new JLabel();
label.setOpaque(true);
fileSystemView = FileSystemView.getFileSystemView();
}
#Override
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean selected,
boolean expanded) {
File file = (File)value;
label.setIcon(fileSystemView.getSystemIcon(file));
label.setText(fileSystemView.getSystemDisplayName(file));
label.setToolTipText(file.getPath());
if (selected) {
label.setBackground(backgroundSelectionColor);
label.setForeground(textSelectionColor);
} else {
label.setBackground(backgroundNonSelectionColor);
label.setForeground(textNonSelectionColor);
}
return label;
}
}