如何通过拖放在jtable中交换单元格的值 [英] How to swap value of cell in jtable by drag and drop
问题描述
我想把表中的数据从一张表交换到另一张表中(注意:我只有两列)。
I would like to swap the data of my table from one table to another IN THE SAME COLUMN (Note: I have only two columns).
我的问题是我不能交换价值。此外,我希望交换仅在同一列上启用,否则表值将重置为其原始值。
My problem is I cannot swap the value. Also, I want the swapping to be enabled only on the same column, otherwise, the table values will reset to its original values.
这是我的代码:
JTable table_1 = new JTable(model);
table_1.setPreferredScrollableViewportSize(new Dimension(300, 120));
table_1.setDragEnabled(true);
table_1.setDropMode(DropMode.USE_SELECTION);
table_1.setTransferHandler(new TransferHelper());
table_1.setRowSelectionAllowed(false);
table_1.setCellSelectionEnabled(true);
我的TransferHelper类:
My TransferHelper Class:
class TransferHelper extends TransferHandler {
private static final long serialVersionUID = 1L;
public TransferHelper() {
}
@Override
public int getSourceActions(JComponent c) {
return MOVE;
}
@Override
protected Transferable createTransferable(JComponent source) {
String data = (String) ((JTable) source).getModel().getValueAt(((JTable) source).getSelectedRow(), ((JTable) source).getSelectedColumn());
return new StringSelection(data);
}
@Override
protected void exportDone(JComponent source, Transferable data, int action) {
((JTable) source).getModel().setValueAt("", ((JTable) source).getSelectedRow(), ((JTable) source).getSelectedColumn());
}
@Override
public boolean canImport(TransferSupport support) {
return true;
}
@Override
public boolean importData(TransferSupport support) {
JTable jt = (JTable) support.getComponent();
try {
jt.setValueAt(support.getTransferable().getTransferData(DataFlavor.stringFlavor), jt.getSelectedRow(), jt.getSelectedColumn());
} catch (UnsupportedFlavorException ex) {
} catch (IOException ex) {
}
return super.importData(support);
}
}
推荐答案
这实际上是一个相当涉及的过程。
Okay, this is actually a rather involved process.
Drag'n'Drop不是一个简单的过程,它是相当复杂和涉及的。这种复杂性带来灵活性
Drag'n'Drop is not a simple process, it's quite complex and involved. With this complexity comes flexibility
以这种方式交换值与说话不同。移动某些东西时,您可以从源代码中将其放在目标中,在这里我们正在交换源和目标之间的值,这意味着我们需要比API通常可用的更多信息。
Swapping values in this way isn't the same as "moving" per say. When moving something, you take it from the source and place it in the target, here we are swapping values between the source and target, this means we need more information than is generally available via the API
首先,您将需要一个自定义类来保存要导出的数据,因为我们正在移动数据,这将需要一些其他信息,特别是源组件。 ..
First of all, you're going to need a custom class to hold the data to be exported, because we're moving data, this is going to require some additional information, in particular, the source component...
以下只是一个简单的包装器。我们可以完全导出 JTable
,但我想演示一个拖放式的基本概念。
The following is just a simple wrapper. We could export the JTable
entirely, but I wanted to demonstrate a basic concept of drag-n-drop...
import javax.swing.JTable;
public class CellData {
private JTable table;
public CellData(JTable table) {
this.table = table;
}
public int getColumn() {
return table.getSelectedColumn();
}
public String getValue() {
int row = table.getSelectedRow();
int col = table.getSelectedColumn();
return (String) table.getValueAt(row, col);
}
public JTable getTable() {
return table;
}
}
接下来,我们需要一个自定义可转移
来管理我们的数据...
Next, we need a custom Transferable
to manage our data...
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
public class CellDataTransferable implements Transferable {
public static final DataFlavor CELL_DATA_FLAVOR = createConstant(CellData.class, "application/x-java-celldata");
private CellData cellData;
public CellDataTransferable(CellData cellData) {
this.cellData = cellData;
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{CELL_DATA_FLAVOR};
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
boolean supported = false;
for (DataFlavor available : getTransferDataFlavors()) {
if (available.equals(flavor)) {
supported = true;
}
}
return supported;
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
return cellData;
}
static protected DataFlavor createConstant(Class clazz, String name) {
try {
return new DataFlavor(clazz, name);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
最后, TransferHandler
....
public class TransferHelper extends TransferHandler {
private static final long serialVersionUID = 1L;
public TransferHelper() {
}
@Override
public int getSourceActions(JComponent c) {
return MOVE;
}
@Override
protected Transferable createTransferable(JComponent source) {
// Create the transferable
// Because I'm hacking a little, I've included the source table...
JTable table = (JTable) source;
return new CellDataTransferable(new CellData(table));
}
@Override
protected void exportDone(JComponent source, Transferable data, int action) {
}
@Override
public boolean canImport(TransferSupport support) {
// Reject the import by default...
boolean canImport = false;
// Can only import into another JTable
Component comp = support.getComponent();
if (comp instanceof JTable) {
JTable table = (JTable) comp;
// Need the location where the drop might occur
DropLocation dl = support.getDropLocation();
Point dp = dl.getDropPoint();
// Get the column at the drop point
int dragColumn = table.columnAtPoint(dp);
try {
// Get the Transferable, we need to check
// the constraints
Transferable t = support.getTransferable();
CellData cd = (CellData) t.getTransferData(CellDataTransferable.CELL_DATA_FLAVOR);
// Make sure we're not dropping onto ourselves...
if (cd.getTable() != table) {
// Do the columns match...?
if (dragColumn == cd.getColumn()) {
canImport = true;
}
}
} catch (UnsupportedFlavorException | IOException ex) {
ex.printStackTrace();
}
}
return canImport;
}
@Override
public boolean importData(TransferSupport support) {
// Import failed for some reason...
boolean imported = false;
// Only import into JTables...
Component comp = support.getComponent();
if (comp instanceof JTable) {
JTable target = (JTable) comp;
// Need to know where we are importing to...
DropLocation dl = support.getDropLocation();
Point dp = dl.getDropPoint();
int dropCol = target.columnAtPoint(dp);
int dropRow = target.rowAtPoint(dp);
try {
// Get the Transferable at the heart of it all
Transferable t = support.getTransferable();
CellData cd = (CellData) t.getTransferData(CellDataTransferable.CELL_DATA_FLAVOR);
if (cd.getTable() != target) {
// Make sure the columns match
if (dropCol == cd.getColumn()) {
// Get the data from the "dropped" table
String exportValue = (String) target.getValueAt(dropRow, dropCol);
// Get the data from the "dragged" table
String importValue = cd.getValue();
// This is where we swap the values...
// Set the target/dropped tables value
target.setValueAt(importValue, dropRow, dropCol);
// Set the source/dragged tables values
JTable source = cd.getTable();
int row = source.getSelectedRow();
int col = source.getSelectedColumn();
source.setValueAt(exportValue, row, col);
imported = true;
}
}
} catch (UnsupportedFlavorException | IOException ex) {
ex.printStackTrace();
}
}
return imported;
}
}
阅读评论:P
最后,一个可运行的示例...
And finally, a runnable example...
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DropMode;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.TransferHandler;
import static javax.swing.TransferHandler.MOVE;
import javax.swing.TransferHandler.TransferSupport;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class TableSwap {
public static void main(String[] args) {
new TableSwap();
}
public TableSwap() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTable t1 = createTable(0);
JTable t2 = createTable(20);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridLayout(0, 2));
frame.add(new JScrollPane(t1));
frame.add(new JScrollPane(t2));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected JTable createTable(int startAt) {
DefaultTableModel model = new DefaultTableModel(0, 2);
for (int index = 0; index < 10; index++) {
model.addRow(new Object[]{"0x" + (index + startAt), "1x" + (index + startAt)});
}
JTable table = new JTable(model);
table.setDragEnabled(true);
table.setDropMode(DropMode.USE_SELECTION);
table.setTransferHandler(new TransferHelper());
table.setRowSelectionAllowed(false);
table.setCellSelectionEnabled(true);
return table;
}
}
已更新以支持单表
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import javax.swing.DropMode;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.TransferHandler;
import static javax.swing.TransferHandler.MOVE;
import javax.swing.TransferHandler.TransferSupport;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class TableSwap {
public static void main(String[] args) {
new TableSwap();
}
public TableSwap() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JTable t1 = createTable(0);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(t1));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected JTable createTable(int startAt) {
DefaultTableModel model = new DefaultTableModel(0, 2);
for (int index = 0; index < 10; index++) {
model.addRow(new Object[]{"0x" + (index + startAt), "1x" + (index + startAt)});
}
JTable table = new JTable(model);
table.setDragEnabled(true);
table.setDropMode(DropMode.USE_SELECTION);
table.setTransferHandler(new TransferHelper());
table.setRowSelectionAllowed(false);
table.setCellSelectionEnabled(true);
return table;
}
public class CellData {
private final Object value;
private final int col;
private final JTable table;
private final int row;
public CellData(JTable source) {
this.col = source.getSelectedColumn();
this.row = source.getSelectedRow();
this.value = source.getValueAt(row, col);
this.table = source;
}
public int getColumn() {
return col;
}
public Object getValue() {
return value;
}
public JTable getTable() {
return table;
}
public boolean swapValuesWith(int targetRow, int targetCol) {
boolean swapped = false;
if (targetCol == col) {
Object exportValue = table.getValueAt(targetRow, targetCol);
table.setValueAt(value, targetRow, targetCol);
table.setValueAt(exportValue, row, col);
swapped = true;
}
return swapped;
}
}
public static final DataFlavor CELL_DATA_FLAVOR = createConstant(CellData.class, "application/x-java-celldata");
public class CellDataTransferable implements Transferable {
private CellData cellData;
public CellDataTransferable(CellData cellData) {
this.cellData = cellData;
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[]{CELL_DATA_FLAVOR};
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
boolean supported = false;
for (DataFlavor available : getTransferDataFlavors()) {
if (available.equals(flavor)) {
supported = true;
}
}
return supported;
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
return cellData;
}
}
static protected DataFlavor createConstant(Class clazz, String name) {
try {
return new DataFlavor(clazz, name);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public class TransferHelper extends TransferHandler {
private static final long serialVersionUID = 1L;
public TransferHelper() {
}
@Override
public int getSourceActions(JComponent c) {
return MOVE;
}
@Override
protected Transferable createTransferable(JComponent source) {
// Create the transferable
JTable table = (JTable) source;
int row = table.getSelectedRow();
int col = table.getSelectedColumn();
Object value = table.getValueAt(row, col);
return new CellDataTransferable(new CellData(table));
}
@Override
protected void exportDone(JComponent source, Transferable data, int action) {
}
@Override
public boolean canImport(TransferSupport support) {
// Reject the import by default...
boolean canImport = false;
// Can only import into another JTable
Component comp = support.getComponent();
if (comp instanceof JTable) {
JTable target = (JTable) comp;
// Need the location where the drop might occur
DropLocation dl = support.getDropLocation();
Point dp = dl.getDropPoint();
// Get the column at the drop point
int dragColumn = target.columnAtPoint(dp);
try {
// Get the Transferable, we need to check
// the constraints
Transferable t = support.getTransferable();
CellData cd = (CellData) t.getTransferData(CELL_DATA_FLAVOR);
// Make sure we're not dropping onto ourselves...
if (cd.getTable() == target) {
// Do the columns match...?
if (dragColumn == cd.getColumn()) {
canImport = true;
}
}
} catch (UnsupportedFlavorException | IOException ex) {
ex.printStackTrace();
}
}
return canImport;
}
@Override
public boolean importData(TransferSupport support) {
// Import failed for some reason...
boolean imported = false;
// Only import into JTables...
Component comp = support.getComponent();
if (comp instanceof JTable) {
JTable target = (JTable) comp;
// Need to know where we are importing to...
DropLocation dl = support.getDropLocation();
Point dp = dl.getDropPoint();
int dropCol = target.columnAtPoint(dp);
int dropRow = target.rowAtPoint(dp);
try {
// Get the Transferable at the heart of it all
Transferable t = support.getTransferable();
CellData cd = (CellData) t.getTransferData(CELL_DATA_FLAVOR);
if (cd.getTable() == target) {
if (cd.swapValuesWith(dropRow, dropCol)) {
imported = true;
}
}
} catch (UnsupportedFlavorException | IOException ex) {
ex.printStackTrace();
}
}
return imported;
}
}
}
这篇关于如何通过拖放在jtable中交换单元格的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!