您的位置:首页 > 其它

JList的拖拽排序实现

2013-04-16 20:00 281 查看
最近实现了一个封装后的支持拖拽排序的JList,以下为源代码

重点关注三点:

1、定义拖拽源

2、定义放置目标

3、定义数据传输格式

其中拖起源定义(DragSource)见37-38行,分别定义支持拖拽的组件,拖拽类型以及拖拽监听器定义放置目标(DropTarget)见39行,分别定义接受拖拽的组件以及对应drop监听

数据传输格式(Transferable)见47行,定义拖拽过程中数据传输类型,此处为自定义的数据传输对象ReportObjTransferable,具体参见下方代码

public class ReorderableList extends JList
implements
DragSourceListener,
DropTargetListener,
DragGestureListener {

private static final long serialVersionUID = -961840807598972987L;
/**
* 拖源
*/
DragSource dragSource;
/**
* 放置目标
*/
DropTarget dropTarget;
/**
* 放置对象
*/
Object dropTargetCell;
/**
* 被拖对象index
*/
int draggedIndex = -1;

/**
* 获取放置对象
*
* @return
*/
public Object getDropTargetCell() {
return dropTargetCell;
}

public ReportReorderableList() {
super();
dragSource =  DragSource.getDefaultDragSource();
dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, this);
dropTarget = new DropTarget(this, this);
}

public void dragGestureRecognized(DragGestureEvent dge) {
Point clickPoint = dge.getDragOrigin();
int index = locationToIndex(clickPoint);
if (index == -1) return;
Object target = getModel().getElementAt(index);
Transferable trans = new ReportObjTransferable(target);
draggedIndex = index;
dragSource.startDrag(dge, Cursor.getDefaultCursor(), trans, this);
}

public void dragEnter(DropTargetDragEvent dtde) {
if (dtde.getSource() != dropTarget)
dtde.rejectDrag();
else {
dtde.acceptDrag(DnDConstants.ACTION_COPY_OR_MOVE);
}
}

public void dragOver(DropTargetDragEvent dtde) {

if (dtde.getSource() != dropTarget) dtde.rejectDrag();
// 拿到拖放的目标位置
Point dragPoint = dtde.getLocation();
int index = locationToIndex(dragPoint);
if (index == -1)
dropTargetCell = null;
else
dropTargetCell = getModel().getElementAt(index);
repaint();
}

public void dropActionChanged(DropTargetDragEvent dtde) {}

public void dragExit(DropTargetEvent dte) {}

public void drop(DropTargetDropEvent dtde) {
if (dtde.getSource() != dropTarget) {
dtde.rejectDrop();
return;
}
Point dropPoint = dtde.getLocation();
int index = locationToIndex(dropPoint);
boolean dropped = false;
try {
DefaultListModel mod = (DefaultListModel) getModel();
Object dragged = dtde.getTransferable().getTransferData(ReportDataFlavor.localObjectFlavor);
// 判断拖拽的对象是否在JList内以及是否已含有当前拖拽对象,不满足条件则不允许放置
if ((index == -1 && mod.size()>0) || (index == draggedIndex && index!=-1) || (draggedIndex == -1 && mod.contains(dragged))) {
dtde.rejectDrop();
return;
}
dtde.acceptDrop(DnDConstants.ACTION_MOVE);
// 不是从当前面板拖拽的对象,则添加
if (draggedIndex == -1) {
mod.add(mod.getSize(), dragged);
} else {
// 从当前面板拖拽的对象,则进行顺序调整
boolean sourceBeforeTarget = (draggedIndex < index);
mod.remove(draggedIndex);
mod.add((sourceBeforeTarget ? index - 1 : index), dragged);
}
dropped = true;
} catch (Exception e) {
e.printStackTrace();
}
dtde.dropComplete(dropped);
}

public void add(Object obj){
DefaultListModel mod = (DefaultListModel) getModel();
mod.addElement(obj);
}

public void dragEnter(DragSourceDragEvent dsde) {}

public void dragOver(DragSourceDragEvent dsde) {}

public void dropActionChanged(DragSourceDragEvent dsde) {}

public void dragExit(DragSourceEvent dse) {}

public void dragDropEnd(DragSourceDropEvent dsde) {
dropTargetCell = null;
draggedIndex = -1;
repaint();
}

}


public class ReportObjTransferable implements Transferable {
Object object;
static DataFlavor[] supportedFlavors = {ReportDataFlavor.localObjectFlavor};

public ReportObjTransferable(Object obj) {
this.object = obj;
}

public Object getTransferData(DataFlavor df) throws UnsupportedFlavorException, IOException {
if (isDataFlavorSupported(df))
return object;
else
throw new UnsupportedFlavorException(df);
}

public boolean isDataFlavorSupported(DataFlavor df) {
return (df.equals(ReportDataFlavor.localObjectFlavor));
}

public DataFlavor[] getTransferDataFlavors() {
return supportedFlavors;
}

}


public class ReportDataFlavor {
/**
* swing控件
*/
public static DataFlavor componentFlavor = createConstant(JComponent.class,
JComponent.class.getName());   /**
* 本地对象类型
*/
public static DataFlavor localObjectFlavor = createConstant(DataFlavor.javaJVMLocalObjectMimeType);

/**
* 数据类型构造
*
* @param rc
* @param prn
* @return
*/
static private DataFlavor createConstant(Class rc, String prn) {
try {
return new DataFlavor(rc, prn);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

static private DataFlavor createConstant(String mimeType) {
try {
return new DataFlavor(DataFlavor.javaJVMLocalObjectMimeType);
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
return null;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: