且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在JTable中用鼠标移动行

更新时间:2023-12-04 10:05:10

我认为JList的项目交换/dropmodedemo.html"rel =" nofollow noreferrer> Swing教程也将有所帮助.

I think that ListTransferHandler.java for item swapping of JList in the Swing tutorial will be also helpful.

这是我为JTable修改ListTransferHandler的示例:

import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
import java.awt.event.*;
import java.io.IOException;
import java.util.*;
import java.util.List;
import javax.activation.*;
import javax.swing.*;
import javax.swing.table.*;

public final class TableRowsDnDTest {
  private final TransferHandler handler = new TableRowTransferHandler();
  private final String[] columnNames = {"String", "Integer", "Boolean"};
  private final Object[][] data = {
    {"AAA", 12, true}, {"aaa", 1, false},
    {"BBB", 13, true}, {"bbb", 2, false},
    {"CCC", 15, true}, {"ccc", 3, false},
    {"DDD", 17, true}, {"ddd", 4, false},
    {"EEE", 18, true}, {"eee", 5, false},
    {"FFF", 19, true}, {"fff", 6, false},
    {"GGG", 92, true}, {"ggg", 0, false}
  };
  private final TableModel model = new DefaultTableModel(data, columnNames) {
    @Override public Class<?> getColumnClass(int column) {
      switch (column) {
      case 0:
        return String.class;
      case 1:
        return Number.class;
      case 2:
        return Boolean.class;
      default:
        return super.getColumnClass(column);
      }
    }
  };
  private final JTable table = new JTable(model);

  public JComponent makeUI() {
    table.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setTransferHandler(handler);
    table.setDropMode(DropMode.INSERT_ROWS);
    table.setDragEnabled(true);
    table.setFillsViewportHeight(true);
    //table.setAutoCreateRowSorter(true); //XXX

    //Disable row Cut, Copy, Paste
    ActionMap map = table.getActionMap();
    Action dummy = new AbstractAction() {
      @Override public void actionPerformed(ActionEvent e) { /* Dummy action */ }
    };
    map.put(TransferHandler.getCutAction().getValue(Action.NAME),   dummy);
    map.put(TransferHandler.getCopyAction().getValue(Action.NAME),  dummy);
    map.put(TransferHandler.getPasteAction().getValue(Action.NAME), dummy);

    JPanel p = new JPanel(new BorderLayout());
    p.add(new JScrollPane(table));
    p.setBorder(BorderFactory.createTitledBorder("Drag & Drop JTable"));
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new TableRowsDnDTest().makeUI());
      f.setSize(320, 240);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

//Demo - BasicDnD (Drag and Drop and Data Transfer) https://docs.oracle.com/javase/tutorial/uiswing/dnd/basicdemo.html
//Demo - DropDemo (Drag and Drop and Data Transfer) https://docs.oracle.com/javase/tutorial/uiswing/dnd/dropmodedemo.html
//@see https://docs.oracle.com/javase/tutorial/uiswing/examples/dnd/DropDemoProject/src/dnd/ListTransferHandler.java
//@see https://github.com/aterai/java-swing-tips/blob/master/DnDReorderTable/src/java/example/TableRowsDnDTest.java
class TableRowTransferHandler extends TransferHandler {
  private final DataFlavor localObjectFlavor;
  private int[] indices;
  private int addIndex = -1; //Location where items were added
  private int addCount; //Number of items added.

  protected TableRowTransferHandler() {
    super();
    localObjectFlavor = new ActivationDataFlavor(Object[].class, DataFlavor.javaJVMLocalObjectMimeType, "Array of items");
  }
  @Override protected Transferable createTransferable(JComponent c) {
    JTable table = (JTable) c;
    DefaultTableModel model = (DefaultTableModel) table.getModel();
    List<Object> list = new ArrayList<>();
    indices = table.getSelectedRows();
    for (int i : indices) {
      list.add(model.getDataVector().get(i));
    }
    Object[] transferedObjects = list.toArray();
    return new DataHandler(transferedObjects, localObjectFlavor.getMimeType());
  }
  @Override public boolean canImport(TransferHandler.TransferSupport info) {
    JTable table = (JTable) info.getComponent();
    boolean isDropable = info.isDrop() && info.isDataFlavorSupported(localObjectFlavor);
    table.setCursor(isDropable ? DragSource.DefaultMoveDrop : DragSource.DefaultMoveNoDrop);
    return isDropable;
  }
  @Override public int getSourceActions(JComponent c) {
    return TransferHandler.MOVE;
  }
  @Override public boolean importData(TransferHandler.TransferSupport info) {
    if (!canImport(info)) {
      return false;
    }
    TransferHandler.DropLocation tdl = info.getDropLocation();
    if (!(tdl instanceof JTable.DropLocation)) {
      return false;
    }
    JTable.DropLocation dl = (JTable.DropLocation) tdl;
    JTable target = (JTable) info.getComponent();
    DefaultTableModel model = (DefaultTableModel) target.getModel();
    int index = dl.getRow();
    int max = model.getRowCount();
    if (index < 0 || index > max) {
      index = max;
    }
    addIndex = index;
    target.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    try {
      Object[] values = (Object[]) info.getTransferable().getTransferData(localObjectFlavor);
      addCount = values.length;
      for (int i = 0; i < values.length; i++) {
        int idx = index++;
        model.insertRow(idx, (Vector) values[i]);
        target.getSelectionModel().addSelectionInterval(idx, idx);
      }
      return true;
    } catch (UnsupportedFlavorException | IOException ex) {
      ex.printStackTrace();
    }
    return false;
  }
  @Override protected void exportDone(JComponent c, Transferable data, int action) {
    cleanup(c, action == TransferHandler.MOVE);
  }

  //If the remove argument is true, the drop has been
  //successful and it's time to remove the selected items
  //from the list. If the remove argument is false, it
  //was a Copy operation and the original list is left
  //intact.
  protected void cleanup(JComponent c, boolean remove) {
    if (remove && indices != null) {
      c.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
      DefaultTableModel model = (DefaultTableModel)((JTable) c).getModel();
      //If we are moving items around in the same list, we
      //need to adjust the indices accordingly, since those
      //after the insertion point have moved.
      if (addCount > 0) {
        for (int i = 0; i < indices.length; i++) {
          if (indices[i] >= addIndex) {
            indices[i] += addCount;
          }
        }
      }
      for (int i = indices.length - 1; i >= 0; i--) {
        model.removeRow(indices[i]);
      }
    }
    indices  = null;
    addCount = 0;
    addIndex = -1;
  }
}