将文件从OS拖放到JTable java中

时间:2012-11-30 05:51:30

标签: java swing file drag-and-drop jtable

有人能告诉我我做错了什么吗?我能够使用常规面板进行拖放操作,但现在尝试使用表格,我无法对其进行排序。我对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 (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);

            }
        });

    }

}

1 个答案:

答案 0 :(得分:7)

我个人会抛弃滚动窗格上的放置目标,这会给你带来很多问题。

你的掉落方法有点诡异......

这是一个坏主意......

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

基本上,您尝试从transferable中提取文件列表,无论操作成功与否,您都尝试使用它?您根本不会对返回值进行验证...

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

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

拒绝表格

的拖拽“外部”

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

要在用户拖动时拒绝操作,您需要覆盖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();
    }
}

接受拖动表的“外部”

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

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