【问题标题】:drag and drop files from OS into JTable java将文件从操作系统拖放到 JTable java
【发布时间】:2012-11-30 05:51:30
【问题描述】:

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

            }
        });

    }

}

【问题讨论】:

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


    【解决方案1】:

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

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

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

    您的放置代码通常并不真正关心放置发生在哪一列,因为您已经有名称和大小列,所以我实际上完全忽略了这一点。

    至于行,现在你有两个选择。当用户没有放在现有行上时,您要么添加新行,要么拒绝尝试。

    拒绝拖动的表格“外部”

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

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

    注意。这将在放置点插入行,将所有现有行向下推,或者如果没有放在现有行上,则将它们添加到末尾...

    测试代码

    这是我用来测试代码的完整运行示例...

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

    【讨论】:

    • 是的。代码有点古怪,但我试图先让拖放工作。我还是 DnD 的新手。至于我想让 drop 成为新行的行。我以为这就是我正在做的。我该怎么做?
    • 您需要访问表模型。看到你已经在使用DefaultTableModel,你可以简单地调用DefaultTableModel#addRow(Object[])
    • 好的,我有点困惑。您是从插入新行的下方的 dataflavor 中提取文件吗?我不应该将 fileList 传递给新行吗?还有这是什么 // 在此处插入妄想症...
    • 1- 是的,您应该决定在提取文件列表后插入新行; 2-妄想症是我说检查可能有点过分,您不太可能收到空文件列表; 3-我的示例确实(有点)已经这样做了(将文件名插入第一列,将大小插入第三列)
    • 我添加了一个完全运行的示例,我用它来测试代码思路
    猜你喜欢
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-15
    • 1970-01-01
    相关资源
    最近更新 更多