将文件从OS拖放到JTable java中

有人能告诉我我做错了什么吗? 我能够使用常规面板进行拖放操作,但现在尝试使用表格,我无法对其进行排序。 我对Points和DropTargets感到困惑。 不要介意“添加”按钮。 我觉得我需要先处理DnD。

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 (eg 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); } }); } } 

我个人会抛弃滚动窗格上的放置目标,这会导致很多问题。

你的drop方法有点奇怪……

这是一个坏主意….

 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); 

基本上,您尝试从可转移文件列表中提取文件列表,无论操作是否成功,您都尝试使用它? 根本没有validation返回值…

你丢弃代码通常并不真正关心丢弃发生在哪个列上,因为你已经有了名称和大小列,所以我实际上完全忽略了它。

至于行,现在你有两个选择。 当用户未放弃现有行或您拒绝该尝试时,您可以添加新行。

拒绝拖动表的“外部”

(或拒绝不调用现有行的拖动)

要在用户拖动时拒绝操作,您需要覆盖dragOver方法…

 @Override public synchronized void dragOver(DropTargetDragEvent dtde) { Point point = dtde.getLocation(); int row = table.rowAtPoint(point); if (row < 0) { dtde.rejectDrag(); table.clearSelection(); } else { dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); table.setRowSelectionInterval(row, row); } } 

现在,我在这里开始有点聪明(而不是以聪明的方式)。 基本上,如果用户拖过一行,我就突出显示了它。 这使得下降的位置更加明显。

在你的drop方法中,我还会做一些额外的检查......

 @Override public synchronized void drop(DropTargetDropEvent dtde) { Point point = dtde.getLocation(); int row = table.rowAtPoint(point); if (row >= 0) { if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); Transferable t = dtde.getTransferable(); List fileList = null; try { fileList = (List) t.getTransferData(DataFlavor.javaFileListFlavor); if (fileList.size() > 0) { table.clearSelection(); Point point = dtde.getLocation(); int row = table.rowAtPoint(point); DefaultTableModel model = (DefaultTableModel) table.getModel(); model.setValueAt(f.getAbsolutePath(), row, 0); model.setValueAt(f.length(), row, 2); } } catch (UnsupportedFlavorException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } else { dtde.rejectDrop(); } } else { dtde.rejectDrop(); } } 

接受Drag在表格的“外部”

这个过程相对来说是相同的,除了现在我们可以抛弃原本会被用来拒绝拖放的条件(显然)

 @Override public synchronized void dragOver(DropTargetDragEvent dtde) { Point point = dtde.getLocation(); int row = table.rowAtPoint(point); if (row < 0) { table.clearSelection(); } else { table.setRowSelectionInterval(row, row); } dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); } 

drop

 @Override public synchronized void drop(DropTargetDropEvent dtde) { if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); Transferable t = dtde.getTransferable(); List fileList = null; try { fileList = (List) t.getTransferData(DataFlavor.javaFileListFlavor); if (fileList.size() > 0) { table.clearSelection(); Point point = dtde.getLocation(); int row = table.rowAtPoint(point); DefaultTableModel model = (DefaultTableModel) table.getModel(); for (Object value : fileList) { if (value instanceof File) { File f = (File) value; if (row < 0) { System.out.println("addRow"); model.addRow(new Object[]{f.getAbsolutePath(), "", f.length(), "", ""}); } else { System.out.println("insertRow " + row); model.insertRow(row, new Object[]{f.getAbsolutePath(), "", f.length(), "", ""}); row++; } } } } } catch (UnsupportedFlavorException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } else { dtde.rejectDrop(); } } 

注意。 这将在drop point处插入行,将所有现有行向下推或如果未在现有行上删除,则将它们添加到结尾...

测试代码

这个用于测试代码的完整运行示例...

 public class DropTable { public static void main(String[] args) { new DropTable(); } public DropTable() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame(); 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 JTable table; private JScrollPane scroll; private DefaultTableModel tm = new DefaultTableModel(new String[]{"File", "File Type", "Size", "Status"}, 0); public DropPane() { table = new JTable(); table.setShowGrid(true); table.setShowHorizontalLines(true); table.setShowVerticalLines(true); table.setGridColor(Color.GRAY); table.setModel(tm); table.setFillsViewportHeight(true); table.setPreferredSize(new Dimension(500, 300)); scroll = new JScrollPane(table); table.setDropTarget(new DropTarget() { @Override public synchronized void dragOver(DropTargetDragEvent dtde) { Point point = dtde.getLocation(); int row = table.rowAtPoint(point); if (row < 0) { table.clearSelection(); } else { table.setRowSelectionInterval(row, row); } dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE); } @Override public synchronized void drop(DropTargetDropEvent dtde) { if (dtde.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) { dtde.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE); Transferable t = dtde.getTransferable(); List fileList = null; try { fileList = (List) t.getTransferData(DataFlavor.javaFileListFlavor); if (fileList.size() > 0) { table.clearSelection(); Point point = dtde.getLocation(); int row = table.rowAtPoint(point); DefaultTableModel model = (DefaultTableModel) table.getModel(); for (Object value : fileList) { if (value instanceof File) { File f = (File) value; if (row < 0) { model.addRow(new Object[]{f.getAbsolutePath(), "", f.length(), "", ""}); } else { model.insertRow(row, new Object[]{f.getAbsolutePath(), "", f.length(), "", ""}); row++; } } } } } catch (UnsupportedFlavorException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } else { dtde.rejectDrop(); } } }); add(scroll, BorderLayout.CENTER); } } }