//获得目标表格的放置行 private int getDropRow(FileTable ft) { JTable.DropLocation dl = ft.getDropLocation(); int i = dl.getRow(); return i == -1 ? ft.getRowCount() : i; } } 下面是moveRow的方法,实际上是从JDK的源代码里拷贝出来的, gcd和rotate是实际操作代码,moveRow是包装一下,在移动过后要更新一下表格视图的。 public void moveRow( int start, int end, int to ) { int shift = to - start; int first, last; if ( shift < 0 ) { first = to; last = end; } else { first = start; last = to + end - start; } rotate( dataVector, first, last + 1, shift ); //这个就是更新视图的方法 updateNewNames( first, last + 1); //fireTableRowsUpdated( first, last ); } private static int gcd( int i, int j ) { return (j == 0) ? i : gcd( j, i % j ); } private static void rotate( Vector<Vector<Object>> dataVector2, int a, int b, int shift ) { int size = b - a; int r = size - shift; int g = gcd( size, r ); for ( int i = 0; i < g; i++ ) { int to = i; Vector<Object> tmp = dataVector2.elementAt( a + to ); for ( int from = (to + r) % size; from != i; from = (to + r) % size ) { dataVector2.setElementAt( dataVector2.elementAt( a + from ), a + to ); to = from; } dataVector2.setElementAt( tmp, a + to ); } }
现在我没时间了,晚上回来如果还没有人回答的话,再跟你说吧。
http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html
这个里面有你想要的效果的例子 自己找找看吧
下面是Transferable类:package org.qusic.java.BatchRename.datatransfer;import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.File;
import java.io.IOException;
import java.util.Vector;
public class FileTableTransferable implements Transferable {
//这个Transferable所支持的数据类型
private static final DataFlavor[] flavors = {
DataFlavor.javaFileListFlavor,
new DataFlavor(int[].class, "X-test/test; class=<int[]>; foo=bar") };
//因为我用到了两种数据,所以有两个data,一个是File,用来拖动文件的
private Vector<File> dataList = null; //一个是int数组,这个就是你要的了,这个数组里面保存的就是要拖动的行号
private int[] data = null;
//File的构造方法
public FileTableTransferable( File... data) {
dataList = new Vector<File>();
for( int i = 0; i < data.length; i++) {
dataList.add( data[i] );
}
dataList.trimToSize();
}
//这个就是行号的构造方法了,提供一个开始行和结束行,也就是选择的开始和结束索引
public FileTableTransferable(int start, int end) {
data = new int[] {start, end};
}
//这个方法就是在别的地方要获取数据的方法了,根据不同的flavor来返回不同的数据
@Override
public Object getTransferData( DataFlavor flavor ) throws UnsupportedFlavorException, IOException {
if(flavors[0].equals( flavor )) {
return dataList;
}
if( flavors[1].equals( flavor )) {
return data;
}
throw new UnsupportedFlavorException( flavor );
} @Override
public DataFlavor[] getTransferDataFlavors() {
return flavors;
} @Override
public boolean isDataFlavorSupported( DataFlavor flavor ) {
if( dataList != null ) {
return flavors[0].equals( flavor );
}else {
return flavors[1].equals( flavor );
}
}}
下面就是TransferHandler类了:package org.qusic.java.BatchRename.datatransfer;import java.awt.Component;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.io.File;
import java.util.List;import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.TransferHandler;import org.qusic.java.BatchRename.ui.FileTable;
public class FileTableTransferHander extends TransferHandler {
private static final DataFlavor[] flavors = {
DataFlavor.javaFileListFlavor,
new DataFlavor(int[].class, "X-test/test; class=<int[]>; foo=bar") };
private Object source = null;
@Override
public boolean canImport( TransferSupport support ) {
if( support.isDataFlavorSupported( flavors[0] )) {
return true;
}
if( support.isDataFlavorSupported( flavors[1] ) && source == support.getComponent()) {
return true;
}
return false;
} //这里时就初始化Transferable的地方了,就是获得表格选择的RowIndex
@Override
protected Transferable createTransferable( JComponent c ) {
if(!(c instanceof FileTable) ) {
return null;
}
FileTable ft = (FileTable)c;
int[] indexes = ft.getSelectedRows();
if( indexes.length == 0) return null;
source = ft;
return new FileTableTransferable(indexes[0],indexes[indexes.length - 1]);
} @Override
protected void exportDone( JComponent source, Transferable data, int action ) {
source = null;
} //导入数据的方法,根据不同的Transferable调用不同的方法来做,具体在下面
@Override
public boolean importData( TransferSupport support ) {
Component c = support.getComponent();
if(!(c instanceof FileTable)) {
return false;
}
FileTable ft = (FileTable)c;
Transferable t = support.getTransferable();
try {
if( support.isDataFlavorSupported( flavors[0] )) {
List<?> data = (List<?>)t.getTransferData(flavors[0]);
if( data != null ) {
importFiles(ft, data.toArray( new File[data.size()] ));
return true;
}
}
if( support.isDataFlavorSupported( flavors[1] ) && source == c) {
int[] data = (int[]) t.getTransferData( flavors[1] );
if( data != null ) {
moveRows(ft, data);
return true;
}
}
}catch(Exception e) {
e.printStackTrace();
}
return false;
} @Override
public int getSourceActions( JComponent c ) {
return COPY_OR_MOVE;
}
//导入文件列表
private void importFiles(FileTable ft, File[] files) {
boolean b = ft.insertRows( getDropRow(ft), files );
if( !b ) {
JOptionPane.showMessageDialog(ft,
"<html>有一个或多个文件没有添加,可能是如下原因:<br>" +
"<ul><li>列表中已经存在这个文件</li><li>目录不能被导入到列表中</li>");
}
}
//这个就是移动表格行了
private void moveRows(FileTable ft, int[] data) {
//moveRow这个方法是实际上是调用TableModel的方法,我会在下面把代码贴出来
ft.moveRow( data[0], data[data.length - 1], getDropRow(ft) );
}
//获得目标表格的放置行
private int getDropRow(FileTable ft) {
JTable.DropLocation dl = ft.getDropLocation();
int i = dl.getRow();
return i == -1 ? ft.getRowCount() : i;
}
}
下面是moveRow的方法,实际上是从JDK的源代码里拷贝出来的,
gcd和rotate是实际操作代码,moveRow是包装一下,在移动过后要更新一下表格视图的。 public void moveRow( int start, int end, int to ) {
int shift = to - start;
int first, last;
if ( shift < 0 ) {
first = to;
last = end;
}
else {
first = start;
last = to + end - start;
}
rotate( dataVector, first, last + 1, shift );
//这个就是更新视图的方法
updateNewNames( first, last + 1);
//fireTableRowsUpdated( first, last );
} private static int gcd( int i, int j ) {
return (j == 0) ? i : gcd( j, i % j );
} private static void rotate( Vector<Vector<Object>> dataVector2, int a, int b, int shift ) {
int size = b - a;
int r = size - shift;
int g = gcd( size, r );
for ( int i = 0; i < g; i++ ) {
int to = i;
Vector<Object> tmp = dataVector2.elementAt( a + to );
for ( int from = (to + r) % size; from != i; from = (to + r) % size ) {
dataVector2.setElementAt( dataVector2.elementAt( a + from ), a + to );
to = from;
}
dataVector2.setElementAt( tmp, a + to );
}
}
看看每个方法的说明。
但是FileTable 这个指哪个Table呢,因为报错。
是找到moveRow方法,然后调用的问题,你也可以获得到TableModel,直接调用TableModel的moveRow方法,
前提是你的TablModel或者Table支持moveRow方法,也就是这个方法你必须写好。
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;import javax.swing.JComponent;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.basic.BasicTableUI;
import javax.swing.table.TableModel;public class DragDropRowTableUI extends BasicTableUI {
private boolean draggingRow = false;
private int startDragPoint;
private int dyOffset;
protected MouseInputListener createMouseInputListener() {
return new DragDropRowMouseInputHandler();
}
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (draggingRow) {
g.setColor(table.getParent().getBackground());
Rectangle cellRect = table.getCellRect(table.getSelectedRow(), 0, false);
g.copyArea(cellRect.x, cellRect.y, table.getWidth(), table.getRowHeight(), cellRect.x, dyOffset);
if (dyOffset < 0) {
g.fillRect(cellRect.x, cellRect.y + (table.getRowHeight() + dyOffset), table.getWidth(), (dyOffset * -1));
} else {
g.fillRect(cellRect.x, cellRect.y, table.getWidth(), dyOffset);
}
}
}
class DragDropRowMouseInputHandler extends MouseInputHandler {
public void mousePressed(MouseEvent e) {
super.mousePressed(e);
startDragPoint = (int)e.getPoint().getY();
}
public void mouseDragged(MouseEvent e) {
int fromRow = table.getSelectedRow();
if (fromRow >= 0) {
draggingRow = true;
int rowHeight = table.getRowHeight();
int middleOfSelectedRow = (rowHeight * fromRow) + (rowHeight / 2);
int toRow = -1;
int yMousePoint = (int)e.getPoint().getY();
if (yMousePoint < (middleOfSelectedRow - rowHeight)) {
// Move row up
toRow = fromRow - 1;
} else if (yMousePoint > (middleOfSelectedRow + rowHeight)) {
// Move row down
toRow = fromRow + 1;
}
if (toRow >= 0 && toRow < table.getRowCount()) {
TableModel model = table.getModel();
for (int i = 0; i < model.getColumnCount(); i++) {
Object fromValue = model.getValueAt(fromRow, i);
Object toValue = model.getValueAt(toRow, i);
model.setValueAt(toValue, fromRow, i);
model.setValueAt(fromValue, toRow, i);
}
table.setRowSelectionInterval(toRow, toRow);
startDragPoint = yMousePoint;
}
dyOffset = (startDragPoint - yMousePoint) * -1;
table.repaint();
}
}
public void mouseReleased(MouseEvent e){
super.mouseReleased(e);
draggingRow = false;
table.repaint();
}
}
} 这个是它实现的类。直接在JTable里面调用这个类就OK .
table.setUI(new DragDropRowTableUI());这段时间谢谢各位的帮忙非常感谢