通过拖放重新排列JList [英] Reordering JList with Drag and Drop

查看:213
本文介绍了通过拖放重新排列JList的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了使用拖放方式在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆