我有一些行的JTable。我想当用鼠标移动一行(拖放)时,该行与鼠标和表行一起移动,以便在鼠标移动时重新排序(例如移动JTable的列)。
jsfiddle正是我想要的,但是我必须在java swing(或下面的gif图像)中进行操作。示例来自here,但我听不懂。

java - 在JTable中用鼠标移动行-LMLPHP

我的TransferHandler:

public class TableRowTransferHandler extends TransferHandler {

    private final DataFlavor localObjectFlavor = new ActivationDataFlavor(Integer.class, "application/x-java-Integer;class=java.lang.Integer", "Integer Row Index");
    private JTable table = null;

    private static final Logger logger = Logger.getLogger(TableRowTransferHandler.class.getName());

    public TableRowTransferHandler(JTable table) {
        this.table = table;
    }

    @Override
    protected Transferable createTransferable(JComponent c) {
        assert (c == table);
        return new DataHandler(table.getSelectedRow(), localObjectFlavor.getMimeType());
    }

    @Override
    public boolean canImport(TransferHandler.TransferSupport info) {
        boolean b = info.getComponent() == table && info.isDrop() && info.isDataFlavorSupported(localObjectFlavor);
        table.setCursor(b ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop);
        return b;
    }

    @Override
    public int getSourceActions(JComponent c) {
        return TransferHandler.COPY_OR_MOVE;
    }

    @Override
    public boolean importData(TransferHandler.TransferSupport info) {
        JTable target = (JTable) info.getComponent();
        JTable.DropLocation dl = (JTable.DropLocation) info.getDropLocation();
        int index = dl.getRow();
        int max = table.getModel().getRowCount();
        if (index < 0 || index > max) {
            index = max;
        }
        target.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        try {
            Integer rowFrom = (Integer) info.getTransferable().getTransferData(localObjectFlavor);
            if (rowFrom != -1 && rowFrom != index) {
                ((Reorderable) table.getModel()).reorder(rowFrom, index);
                if (index > rowFrom) {
                    index--;
                }
                target.getSelectionModel().addSelectionInterval(index, index);
                return true;
            }
        } catch (UnsupportedFlavorException | IOException e) {
            e.printStackTrace();
            logger.log(Level.SEVERE, null, e);
        }
        return false;
    }

    @Override
    protected void exportDone(JComponent c, Transferable t, int act) {
        if ((act == TransferHandler.MOVE) || (act == TransferHandler.NONE)) {
            table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
        }
    }
}


这是我用于JTable的简单设置:

    childrenTable.setDragEnabled(true);
    childrenTable.setDropMode(DropMode.INSERT);
    childrenTable.setTransferHandler(new TableRowTransferHandler(childrenTable));
    childrenTable.setRowSelectionAllowed(true);
    childrenTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);


目前,当您使用鼠标在行之间移动行时,只有一条粗线(如下面图片中的红色椭圆所示)。如果不可能做这样的行移动,我希望此粗线显示在整行中(不仅在一个单元格中)。

java - 在JTable中用鼠标移动行-LMLPHP

最佳答案

阅读Swing教程中有关拖放的部分,以了解基础知识。

这是一些我在网上找到的带有自定义TransferHandler来支持JTable的旧代码:

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.IOException;
public class DnD_Demo extends JFrame {
    public DnD_Demo() {
        setTitle("DnD Demo (Version 3)");
        JTextArea tips = new JTextArea("1. Select a row in Table A. " +
                "Press the row again and drag. \n     " +
                "As you drag the cursor icon over Table B, the row that is currently under the cursor highlights " +
                "- the new data will be inserted after the selected row. \n     " +
                "Drop the row onto Table B. Note that the row has been removed from Table A, " +
                "and now appears in Table B. \n" +
                "2. Select two rows from Table A and drop onto Table B. " +
                "Now there are two new rows in Table B. ");
        tips.setEditable(false);
        tips.setBackground(new Color(255,255,204));
        tips.setBorder(new LineBorder(Color.orange,5));
        getContentPane().add(tips,BorderLayout.NORTH);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel(new GridLayout(2,1));
        panel.add(createTable("Table A"));
        panel.add(createTable("Table B"));
        getContentPane().add(panel,BorderLayout.CENTER);
        pack();
    }
    private JPanel createTable(String tableId) {
        DefaultTableModel model = new DefaultTableModel();
        model.addColumn("Column 0");
        model.addColumn("Column 1");
        model.addColumn("Column 2");
        model.addColumn("Column 3");
        model.addRow(new String[]{tableId+" 00", tableId+" 01", tableId+" 02", tableId+" 03"});
        model.addRow(new String[]{tableId+" 10", tableId+" 11", tableId+" 12", tableId+" 13"});
        model.addRow(new String[]{tableId+" 20", tableId+" 21", tableId+" 22", tableId+" 23"});
        model.addRow(new String[]{tableId+" 30", tableId+" 31", tableId+" 32", tableId+" 33"});
        JTable table = new JTable(model);
        table.getTableHeader().setReorderingAllowed(false);
        table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setPreferredSize(new Dimension(400,100));
        table.setDragEnabled(true);
        table.setTransferHandler(new TableTransferHandler());
        JPanel panel = new JPanel();
        panel.add(scrollPane);
        panel.setBorder(BorderFactory.createTitledBorder(tableId));
        return panel;
    }
    public static void main(String[] args) {
        new DnD_Demo().setVisible(true);
    }

    abstract class StringTransferHandler extends TransferHandler {
        protected abstract String exportString(JComponent c);
        protected abstract void importString(JComponent c, String str);
        protected abstract void cleanup(JComponent c, boolean remove);
        protected Transferable createTransferable(JComponent c) {
            return new StringSelection(exportString(c));
        }
        public int getSourceActions(JComponent c) {
            return COPY_OR_MOVE;
        }
        public boolean importData(JComponent c, Transferable t) {
            if (canImport(c, t.getTransferDataFlavors())) {
                try {
                    String str = (String)t.getTransferData(DataFlavor.stringFlavor);
                    importString(c, str);
                    return true;
                } catch (UnsupportedFlavorException ufe) {
                } catch (IOException ioe) {
                }
            }
            return false;
        }
        protected void exportDone(JComponent c, Transferable data, int action) {
            cleanup(c, action == MOVE);
        }
        public boolean canImport(JComponent c, DataFlavor[] flavors) {
            for (int i = 0; i < flavors.length; i++) {
                if (DataFlavor.stringFlavor.equals(flavors[i])) {
                    return true;
                }
            }
            return false;
        }
    }
    class TableTransferHandler extends StringTransferHandler {
        public JTable target;
        public int[] rows = null;
        public int addIndex = -1; //Location where items were added
        public int addCount = 0;  //Number of items added.
        protected String exportString(JComponent c) {
            JTable table = (JTable)c;
            rows = table.getSelectedRows();
            int colCount = table.getColumnCount();
            StringBuffer buff = new StringBuffer();
            for (int i = 0; i < rows.length; i++) {
                for (int j = 0; j < colCount; j++) {
                    Object val = table.getValueAt(rows[i], j);
                    buff.append(val == null ? "" : val.toString());
                    if (j != colCount - 1) {
                        buff.append(",");
                    }
                }
                if (i != rows.length - 1) {
                    buff.append("\n");
                }
            }
            return buff.toString();
        }
        protected void importString(JComponent c, String str) {
            target = (JTable)c;
            DefaultTableModel model = (DefaultTableModel)target.getModel();
            int index = target.getSelectedRow();
            //Prevent the user from dropping data back on itself.
            //For example, if the user is moving rows #4,#5,#6 and #7 and
            //attempts to insert the rows after row #5, this would
            //be problematic when removing the original rows.
            //So this is not allowed.
            if (rows != null && index >= rows[0] - 1 &&
                    index <= rows[rows.length - 1]) {
                rows = null;
                return;
            }
            int max = model.getRowCount();
            if (index < 0) {
                index = max;
            } else {
                index++;
                if (index > max) {
                    index = max;
                }
            }
            addIndex = index;
            String[] values = str.split("\n");
            addCount = values.length;
            int colCount = target.getColumnCount();
            for (int i = 0; i < values.length ; i++) {
                model.insertRow(index++, values[i].split(","));
            }
            //If we are moving items around in the same table, we
            //need to adjust the rows accordingly, since those
            //after the insertion point have moved.
            if (rows!= null && addCount > 0) {
                for (int i = 0; i < rows.length; i++) {
                    if (rows[i] > addIndex) {
                        rows[i] += addCount;
                    }
                }
            }
        }
        protected void cleanup(JComponent c, boolean remove) {
            JTable source = (JTable)c;
            if (remove && rows != null) {
                DefaultTableModel model =
                        (DefaultTableModel)source.getModel();
                for (int i = rows.length - 1; i >= 0; i--) {
                    model.removeRow(rows[i]);
                }
            }
            rows = null;
            addCount = 0;
            addIndex = -1;
        }
    }
}

07-28 02:34
查看更多