通过拖放重新排列JList [英] Reordering JList with Drag and Drop
问题描述
我遇到了使用拖放方式在JList中重新排序元素的问题。下面的代码是一个代码的修改,您可以将元素从一个JList拖到另一个(仅用于一种方式)。我试图使它只能用于一个JList,但是元素甚至不能被拖出列表。所以我想这不可能这样做。任何想法我做错什么或不考虑?
I encountered a problem regarding reordering elements in a JList using Drag and Drop. This following code is a modification of a code where you could drag elements from one JList to another (worked only one way). I tried to make it usable for only one JList, but the elements can't even be dragged out of the list. So I guess it can't be done this way. Any ideas what I'm doing wrong or not taking into consideration?
这个想法是让它在缩略图上使用Jlist,但是由于我甚至不能让它只是使用字符串...我一直在研究几个D'n'D教程,但仍然无法让它工作。
任何帮助不胜感激。
The idea is to get it to work for a Jlist with thumbnails, but since I can't even get it to work with just strings... I have been looking into several D'n'D tutorials, but still I can't get it to work. Any help is appreciated.
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.datatransfer.*;
import java.io.IOException;
public class DragAndDrop extends JFrame {
DefaultListModel<String> transport = new DefaultListModel<String>();
JList<String> transportList = new JList<String>(transport);
public DragAndDrop() {
setLayout(new FlowLayout());
transport.addElement("Bike");
transport.addElement("Car");
transport.addElement("Truck");
transport.addElement("Boat");
JScrollPane transportScroll = new JScrollPane(transportList);
transportScroll.setBorder(new TitledBorder("Transportation"));
add(transportScroll);
transportList.setDragEnabled(true);
transportList.setTransferHandler(new TransferHandler() {
int index;
@Override
public int getSourceActions(JComponent comp) {
return COPY_OR_MOVE;
}
@Override
public Transferable createTransferable(JComponent comp) {
index = transportList.getSelectedIndex();
return new StringSelection(transportList.getSelectedValue());
}
@Override
public void exportDone( JComponent comp, Transferable trans, int action ) {
if (action==MOVE) {
transport.remove(index);
}
}
});
transportList.setDropMode(DropMode.ON);
transportList.setTransferHandler(new TransferHandler() {
@Override
public boolean canImport(TransferHandler.TransferSupport support) {
// data of type string?
return support.isDataFlavorSupported(DataFlavor.stringFlavor);
}
@Override
public boolean importData(TransferHandler.TransferSupport support) {
try {
// convert data to string
String s = (String)support.getTransferable().getTransferData(DataFlavor.stringFlavor);
JList.DropLocation dl = (JList.DropLocation)support.getDropLocation();
transport.add(dl.getIndex(),s);
return true;
}
catch (UnsupportedFlavorException e) {}
catch (IOException e) {}
return false;
}
});
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new DragAndDrop();
}
}
对不起,如果事实证明是重新发布。
PS. Sorry if this turns out to be a re-post.
编辑
我想我得到它固定:不得不不同的transferHandlers - 应该只有一个与所有的方法从第二个一个也是。
EDIT I think I got it fixed: had to different transferHandlers - should only have one with all the methods from the second one as well.
推荐答案
import java.awt.*;
import java.awt.datatransfer.*;
import java.io.*;
import java.util.Arrays;
import javax.activation.*;
import javax.swing.*;
public class DragAndDropTest {
public JComponent makeUI() {
DefaultListModel<Thumbnail> m = new DefaultListModel<>();
for(String s: Arrays.asList("error","information","question","warning")) {
m.addElement(new Thumbnail(s));
}
JList<Thumbnail> list = new JList<>(m);
list.getSelectionModel().setSelectionMode(
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
list.setTransferHandler(new ListItemTransferHandler());
list.setDropMode(DropMode.INSERT);
list.setDragEnabled(true);
//http://java-swing-tips.blogspot.jp/2008/10/rubber-band-selection-drag-and-drop.html
list.setLayoutOrientation(JList.HORIZONTAL_WRAP);
list.setVisibleRowCount(0);
list.setFixedCellWidth(80);
list.setFixedCellHeight(80);
list.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
list.setCellRenderer(new ListCellRenderer<Thumbnail>() {
private final JPanel p = new JPanel(new BorderLayout());
private final JLabel icon = new JLabel((Icon)null, JLabel.CENTER);
private final JLabel label = new JLabel("", JLabel.CENTER);
@Override public Component getListCellRendererComponent(
JList list, Thumbnail value, int index,
boolean isSelected, boolean cellHasFocus) {
icon.setIcon(value.icon);
label.setText(value.name);
label.setForeground(isSelected? list.getSelectionForeground()
: list.getForeground());
p.add(icon);
p.add(label, BorderLayout.SOUTH);
p.setBackground(isSelected? list.getSelectionBackground()
: list.getBackground());
return p;
}
});
return new JScrollPane(list);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override public void run() { createAndShowGUI(); }
});
}
public static void createAndShowGUI() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.getContentPane().add(new DragAndDropTest().makeUI());
f.setSize(320, 240);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class Thumbnail {
public final String name;
public final Icon icon;
public Thumbnail(String name) {
this.name = name;
this.icon = UIManager.getIcon("OptionPane."+name+"Icon");
}
}
//@camickr already suggested above.
//http://docs.oracle.com/javase/tutorial/uiswing/dnd/dropmodedemo.html
class ListItemTransferHandler extends TransferHandler {
private final DataFlavor localObjectFlavor;
private Object[] transferedObjects = null;
public ListItemTransferHandler() {
localObjectFlavor = new ActivationDataFlavor(
Object[].class, DataFlavor.javaJVMLocalObjectMimeType, "Array of items");
}
@SuppressWarnings("deprecation")
@Override protected Transferable createTransferable(JComponent c) {
JList list = (JList) c;
indices = list.getSelectedIndices();
transferedObjects = list.getSelectedValues();
return new DataHandler(transferedObjects, localObjectFlavor.getMimeType());
}
@Override public boolean canImport(TransferSupport info) {
if(!info.isDrop() || !info.isDataFlavorSupported(localObjectFlavor)) {
return false;
}
return true;
}
@Override public int getSourceActions(JComponent c) {
return MOVE; //TransferHandler.COPY_OR_MOVE;
}
@SuppressWarnings("unchecked")
@Override public boolean importData(TransferSupport info) {
if(!canImport(info)) {
return false;
}
JList target = (JList)info.getComponent();
JList.DropLocation dl = (JList.DropLocation)info.getDropLocation();
DefaultListModel listModel = (DefaultListModel)target.getModel();
int index = dl.getIndex();
int max = listModel.getSize();
if(index<0 || index>max) {
index = max;
}
addIndex = index;
try {
Object[] values = (Object[])info.getTransferable().getTransferData(
localObjectFlavor);
addCount = values.length;
for(int i=0; i<values.length; i++) {
int idx = index++;
listModel.add(idx, values[i]);
target.addSelectionInterval(idx, idx);
}
return true;
} catch(UnsupportedFlavorException ufe) {
ufe.printStackTrace();
} catch(IOException ioe) {
ioe.printStackTrace();
}
return false;
}
@Override protected void exportDone(
JComponent c, Transferable data, int action) {
cleanup(c, action == MOVE);
}
private void cleanup(JComponent c, boolean remove) {
if(remove && indices != null) {
JList source = (JList)c;
DefaultListModel model = (DefaultListModel)source.getModel();
if(addCount > 0) {
//http://java-swing-tips.googlecode.com/svn/trunk/DnDReorderList/src/java/example/MainPanel.java
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.remove(indices[i]);
}
}
indices = null;
addCount = 0;
addIndex = -1;
}
private int[] indices = null;
private int addIndex = -1; //Location where items were added
private int addCount = 0; //Number of items added.
}
这篇关于通过拖放重新排列JList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!