现在一直都在弄Java Swing的开发,因本来就不怎么深入的去了解过,对Swing还是处于刚出发的慢跑阶段。前几天一直都被JLabel实现行的拖动困扰着,想达到像JLabel的列头那样拖动的效果,今天终于解决了。现在就拿来分享一下,以后谁碰到这样的需求也不用像我这么头痛了。。。
1、开始的想法是通过对JTable监听鼠标事件,通过MousePressed() 、MouseDragged()、MouseRelessed()这三个事件来处理,重写TransferHandler和Transferable类。但是里面的逻辑一直都么理清。另外是,用选中的行 获得数据生成图片来处理,选中的行数据另外存储起来,当图片拖动的哪一行的时候,释放(MouseRelessed()),图片消失,再把先前保存的数据插入移动到的位置的前一行。图片生成了,但是怎么拖动呢?怎么把图片添加到JTable上面呢,就要实现刷新(而且我也不会),通过加到组件上面(JLabel)上面,结果失败。。。(以后谁有兴趣可以去试试,这两个都应该是可以实现的)
2、刚刚用到了另外的一种方法,当然也是在他人提供的资料下并指点之下才得以完成(当然代码并不是我写,只是帮助了我解决,这东西找起来好麻烦,嘿嘿。。),给JTable设置UI. JTable.setUI(); 这个UI是直接实现了表格的行拖动的,只要直接调用就额可以了。。。
[void setUI(TableUI ui)
设置呈现此组件并进行重新绘制的 L&F 对象。]
****************************************************************************
//实现了表格行的拖动 )
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的表格的行拖动,能达到想列拖动的效果,要用的话可以直接拿过去用
只要设置的个JTable就可以了(JTable.setUI(new DragDropRowTableUI ()));
这样就可以不用管JTable了,表格就具有行拖动的效果了。。。