Can someone show me what I’m doing wrong? I was able to get drag and drop working with a regular panel but now trying with a table and I can’t sort it out. I’m getting confused with the Points and DropTargets. Dont mind the “Add” button. I feel like I need to deal with the DnD first.
public class Table extends JFrame implements ActionListener {
private JTable table;
private JScrollPane scroll;
private JButton add;
private JFileChooser choose;
private JMenuBar menubar;
private JMenu menu;
private JMenuItem file;
private DefaultTableModel tm = new DefaultTableModel(new String[] { "File",
"File Type", "Size", "Status" }, 2);
public Table() {
// String column [] = {"Filename ","File Type", "Size", "Status" };
/*
* Object[][] data = { {"File1", ".jpg","32 MB", "Not Processed"},
* {"File2", ".txt"," 5 Kb", "Not Processed"}, {"File3", ".doc","3 Kb",
* "Not Processed"},
* };
*/
table = new JTable();
table.setModel(tm);
table.setFillsViewportHeight(true);
table.setPreferredSize(new Dimension(500, 300));
scroll = new JScrollPane(table);
table.setDropTarget(new DropTarget() {
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
Point point = dtde.getLocation();
int column = table.columnAtPoint(point);
int row = table.rowAtPoint(point);
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable t = dtde.getTransferable();
List fileList = null;
try {
fileList = (List) t
.getTransferData(DataFlavor.javaFileListFlavor);
} catch (UnsupportedFlavorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File f = (File) fileList.get(0);
table.setValueAt(f.getAbsolutePath(), row, column);
table.setValueAt(f.length(), row, column + 1);
super.drop(dtde);
}
});
scroll.setDropTarget(new DropTarget() {
@Override
public synchronized void drop(DropTargetDropEvent dtde) {
Point point = dtde.getLocation();
int column = table.columnAtPoint(point);
int row = table.rowAtPoint(point);
dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);
Transferable t = dtde.getTransferable();
List fileList = null;
try {
fileList = (List) t
.getTransferData(DataFlavor.javaFileListFlavor);
} catch (UnsupportedFlavorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File f = (File) fileList.get(0);
table.setValueAt(f.getAbsolutePath(), row, column);
table.setValueAt(f.length(), row, column + 1);
// handle drop outside current table (e.g. add row)
super.drop(dtde);
}
});
add(scroll, BorderLayout.CENTER);
menubar = new JMenuBar();
menu = new JMenu("File");
file = new JMenuItem("file");
menu.add(file);
// menubar.add(menu);
add(menu, BorderLayout.NORTH);
ImageIcon icon = new ImageIcon("lock_icon.png");
add = new JButton("Add", icon);
add.addActionListener(this);
JFileChooser choose = new JFileChooser();
choose.addActionListener(this);
}
@Override
public void actionPerformed(ActionEvent e) {
JButton clicked = (JButton) e.getSource();
int returnValue = 0;
if (clicked == add) {
choose = new JFileChooser();
choose.showOpenDialog(null);
if (returnValue == JFileChooser.APPROVE_OPTION) {
File file = choose.getSelectedFile();
file.getAbsolutePath();
}
}
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
Table t = new Table();
t.setDefaultCloseOperation(EXIT_ON_CLOSE);
t.pack();
t.setSize(600, 200);
t.setVisible(true);
t.setTitle("ZipLock");
t.setIconImage(null);
}
});
}
}
I personally would ditch the drop target on the scroll pane, it’s going to cause you to many problems.
Your drop method is a little queezy…
This is a bad idea….
Basically, you try and extract the file list from the transferable, and regardless of the success of the operation, you try and use it ?! You do no validation of the returned value at all…
Your drop code generally doesn’t really care about what column the drop occurred on, as you have name and size columns already, so I’d actually ignore that altogether.
As for the row, now you have two choices. Either you add a new row when the user doesn’t drop on an existing one or you reject the attempt.
Reject drag’s “outside” of table
(Or reject drags that don’t call over an existing row)
To reject the operation while the user is dragging, you need to override the
dragOvermethod…Now, I’m been a little smart here (and not in the clever way). Basically, if the user has dragged over a row, I’ve highlighted it. This makes it a little more obvious where the drop is going.
In your drop method, I would also make some additional checks…
Accept Drag’s “outside” of the table
The process is relativly the same, except now we can throw away the conditions that would have otherwise caused us to reject the drag/drop (obviously)
And the
dropmethodNote. This will insert rows at the drop point, push all the existing rows down OR if not dropped on an existing row, will add them to the end…
TEST CODE
This a full running example I used to test the code…