1

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

            }
        });

    }

}
4

1 回答 1

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

基本上,您尝试从可传输文件中提取文件列表,并且无论操作是否成功,您都尝试使用它?!您根本不验证返回的值...

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

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

拒绝拖动表格的“外部”

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

要在用户拖动时拒绝操作,您需要覆盖该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);
        }
    }
}
于 2012-11-30T06:27:06.577 回答