使用Java Swing复制到另一个列表时如何在列表中移动?

时间:2015-10-21 19:50:12

标签: java swing drag-and-drop jlist

我有以下程序可以在两个列表之间复制或移动项目,我想用这个作为开发DJ程序来播放音乐的基础。 右侧列表是从我PC上的目录中读取的可用歌曲列表,左侧列表包含我想要播放的歌曲。

所以当我从右到左拖放一首歌曲时,它会被添加到要播放的歌曲列表中,但是当我从左到右播放歌曲时,它应该只是从剧本中删除它列表在左侧,但不影响从本地驱动器读取的右侧列表中的歌曲列表。当我在左侧列表中输入一首歌时,它只是重新排序播放列表,所以如何更改它以便:

[1] When I drag and drop an item in the left list, it moves the item inside the list
[2] When I drag and drop an item from the left list to the right list, it only removes it from left list while does nothing to the right list
[3] When I drag and drop an item from the right list to the left list, it only adds the item to the left list while does nothing to the right list.

import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import javax.activation.*;
import javax.swing.*;
import javax.swing.border.*;

public final class Demo_Drag_And_Drop_List_Panel extends JPanel                // http://ateraimemo.com/Swing/DnDBetweenLists.html
{
  static JRadioButton Copy_Button=new JRadioButton("Copy"),Move_Button=new JRadioButton("Move");

  private Demo_Drag_And_Drop_List_Panel()
  {
    super(new BorderLayout());
    JPanel p=new JPanel(new GridLayout(1,2,10,0));
    TransferHandler h=new ListItemTransferHandler();
    TitledBorder title=BorderFactory.createTitledBorder("Drag & Drop between JLists");
    p.setBorder(title);
    title.setTitleJustification(TitledBorder.CENTER);
    p.add(new JScrollPane(makeList(h)));
    p.add(new JScrollPane(makeList(h)));
    add(p);
    setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    setPreferredSize(new Dimension(500,260));

    JPanel Copy_Or_Move_Option_Panel=new JPanel();

    Copy_Or_Move_Option_Panel.add(Copy_Button);

    Move_Button.setSelected(true);
    Copy_Or_Move_Option_Panel.add(Move_Button);

    //Group the radio buttons.
    ButtonGroup group=new ButtonGroup();
    group.add(Copy_Button);
    group.add(Move_Button);

    add("South",Copy_Or_Move_Option_Panel);
  }

  private static JList<Color> makeList(TransferHandler handler)
  {
    DefaultListModel<Color> listModel=new DefaultListModel<>();
    listModel.addElement(Color.RED);
    listModel.addElement(Color.BLUE);
    listModel.addElement(Color.GREEN);
    listModel.addElement(Color.CYAN);
    listModel.addElement(Color.ORANGE);
    listModel.addElement(Color.PINK);
    listModel.addElement(Color.MAGENTA);
    JList<Color> list=new JList<>(listModel);
    list.setCellRenderer(new DefaultListCellRenderer()
    {
      @Override public Component getListCellRendererComponent(JList list,Object value,int index,boolean isSelected,boolean cellHasFocus)
      {
        Component c=super.getListCellRendererComponent(list,value,index,isSelected,cellHasFocus);
        ((JLabel)c).setForeground((Color)value);
        return c;
      }
    });
    list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    list.setDropMode(DropMode.INSERT);
    list.setDragEnabled(true);
    list.setTransferHandler(handler);

    ActionMap map=list.getActionMap();
    AbstractAction dummy=new AbstractAction()                                  // Disable row Cut, Copy, Paste
    {
      @Override public void actionPerformed(ActionEvent e)
      { /* Dummy action */ }
    };
    map.put(TransferHandler.getCutAction().getValue(Action.NAME),dummy);
    map.put(TransferHandler.getCopyAction().getValue(Action.NAME),dummy);
    map.put(TransferHandler.getPasteAction().getValue(Action.NAME),dummy);

    return list;
  }

  public static void createAndShowGUI()
  {
//    try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); }
//    catch (ClassNotFoundException|InstantiationException|IllegalAccessException|UnsupportedLookAndFeelException ex) { ex.printStackTrace(); }
    JFrame frame=new JFrame("Demo_Drag_And_Drop_List_Panel");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(new Demo_Drag_And_Drop_List_Panel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }

  public static void main(String... args)
  {
    EventQueue.invokeLater(new Runnable()
    {
      @Override public void run() { createAndShowGUI(); }
    });
  }
}

class ListItemTransferHandler extends TransferHandler                          // Demo - BasicDnD (Drag and Drop and Data Transfer)>http://docs.oracle.com/javase/tutorial/uiswing/dnd/basicdemo.html
{
  private final DataFlavor localObjectFlavor;
  private JList source;
  private int[] indices;
  private int addIndex=-1;                                                     // Location where items were added
  private int addCount;                                                        // Number of items added.

  public ListItemTransferHandler()
  {
    super();
    localObjectFlavor=new ActivationDataFlavor(Object[].class,DataFlavor.javaJVMLocalObjectMimeType,"Array of items");
  }

  @Override protected Transferable createTransferable(JComponent c)
  {
    source=(JList)c;
    indices=source.getSelectedIndices();
    @SuppressWarnings("deprecation") Object[] transferedObjects=source.getSelectedValues();
    return new DataHandler(transferedObjects,localObjectFlavor.getMimeType());
  }

  @Override public boolean canImport(TransferSupport info) { return info.isDrop()&&info.isDataFlavorSupported(localObjectFlavor); }

  @Override public int getSourceActions(JComponent c)
  {
    return Demo_Drag_And_Drop_List_Panel.Copy_Button.isSelected()?COPY:MOVE;   // TransferHandler.COPY_OR_MOVE;
  }

  @SuppressWarnings("unchecked")
  @Override public boolean importData(TransferSupport info)
  {
    if (!canImport(info)) return false;
    TransferHandler.DropLocation tdl=info.getDropLocation();
    if (!(tdl instanceof JList.DropLocation)) return false;
    JList.DropLocation dl=(JList.DropLocation)tdl;
    JList target=(JList)info.getComponent();
    DefaultListModel listModel=(DefaultListModel)target.getModel();
    int index=dl.getIndex();
    //boolean insert = dl.isInsert();
    int max=listModel.getSize();
    if (index<0||index>max) index=max;
    addIndex=index;

    try
    {
      Object[] values=(Object[])info.getTransferable().getTransferData(localObjectFlavor);
      for (int i=0;i<values.length;i++)
      {
        int idx=index++;
        listModel.add(idx,values[i]);
        target.addSelectionInterval(idx,idx);
      }
      addCount=target.equals(source)?values.length:0;
      return true;
    }
    catch (UnsupportedFlavorException|IOException ex) { ex.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)
    {
      // If we are moving items around in the same list, we need to adjust the indices accordingly, since those after the insertion point have moved.
      if (addCount>0)
      {
        for (int i=0;i<indices.length;i++) if (indices[i]>=addIndex) indices[i]+=addCount;
      }
      JList source=(JList)c;
      DefaultListModel model=(DefaultListModel)source.getModel();
      for (int i=indices.length-1;i>=0;i--) model.remove(indices[i]);
    }
    indices=null;
    addCount=0;
    addIndex=-1;
  }
}

1 个答案:

答案 0 :(得分:1)

另一种选择是使用Component#setName(String)Component#getName()

  

[2]当我将项目从左侧列表拖放到右侧列表时,   它只会从左侧列表中删除它,而不对右侧列表执行任何操作

if ("songs-right-list".equals(target.getName())
   && "play-left-list".equals(source.getName())) {
  return true;
}
  

[3]当我将项目从右侧列表拖放到左侧列表时,   它只会将项目添加到左侧列表中,而不会向右侧执行任何操作   列表。

if ("play-left-list".equals(target.getName())
    && "songs-right-list".equals(source.getName())) {
  indices = null;
}

<强> DemoDragAndDropListPanel.java

import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.ActionEvent;
import java.io.IOException;
import javax.activation.*;
import javax.swing.*;
import javax.swing.border.*;

public final class DemoDragAndDropListPanel extends JPanel                // http://ateraimemo.com/Swing/DnDBetweenLists.html
{
  static JRadioButton Copy_Button=new JRadioButton("Copy"),Move_Button=new JRadioButton("Move");

  private DemoDragAndDropListPanel()
  {
    super(new BorderLayout());
    JPanel p=new JPanel(new GridLayout(1,2,10,0));
    TransferHandler h=new ListItemTransferHandler();
    TitledBorder title=BorderFactory.createTitledBorder("Drag & Drop between JLists");
    p.setBorder(title);
    title.setTitleJustification(TitledBorder.CENTER);
    p.add(new JScrollPane(makeList("play-left-list", h)));
    p.add(new JScrollPane(makeList("songs-right-list", h)));
    add(p);
    setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
    setPreferredSize(new Dimension(500,260));

    JPanel Copy_Or_Move_Option_Panel=new JPanel();

    Copy_Or_Move_Option_Panel.add(Copy_Button);

    Move_Button.setSelected(true);
    Copy_Or_Move_Option_Panel.add(Move_Button);

    //Group the radio buttons.
    ButtonGroup group=new ButtonGroup();
    group.add(Copy_Button);
    group.add(Move_Button);

    add("South",Copy_Or_Move_Option_Panel);
  }

  private static JList<Color> makeList(String name, TransferHandler handler)
  {
    DefaultListModel<Color> listModel=new DefaultListModel<>();
    listModel.addElement(Color.RED);
    listModel.addElement(Color.BLUE);
    listModel.addElement(Color.GREEN);
    listModel.addElement(Color.CYAN);
    listModel.addElement(Color.ORANGE);
    listModel.addElement(Color.PINK);
    listModel.addElement(Color.MAGENTA);
    JList<Color> list=new JList<>(listModel);
    list.setName(name);
    list.setCellRenderer(new DefaultListCellRenderer()
    {
      @Override public Component getListCellRendererComponent(JList list,Object value,int index,boolean isSelected,boolean cellHasFocus)
      {
        Component c=super.getListCellRendererComponent(list,value,index,isSelected,cellHasFocus);
        ((JLabel)c).setForeground((Color)value);
        return c;
      }
    });
    list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    list.setDropMode(DropMode.INSERT);
    list.setDragEnabled(true);
    list.setTransferHandler(handler);

    ActionMap map=list.getActionMap();
    AbstractAction dummy=new AbstractAction()                                  // Disable row Cut, Copy, Paste
    {
      @Override public void actionPerformed(ActionEvent e)
      { /* Dummy action */ }
    };
    map.put(TransferHandler.getCutAction().getValue(Action.NAME),dummy);
    map.put(TransferHandler.getCopyAction().getValue(Action.NAME),dummy);
    map.put(TransferHandler.getPasteAction().getValue(Action.NAME),dummy);

    return list;
  }

  public static void createAndShowGUI()
  {
//    try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); }
//    catch (ClassNotFoundException|InstantiationException|IllegalAccessException|UnsupportedLookAndFeelException ex) { ex.printStackTrace(); }
    JFrame frame=new JFrame("DemoDragAndDropListPanel");
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(new DemoDragAndDropListPanel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }

  public static void main(String... args)
  {
    EventQueue.invokeLater(new Runnable()
    {
      @Override public void run() { createAndShowGUI(); }
    });
  }
}

class ListItemTransferHandler extends TransferHandler                          // Demo - BasicDnD (Drag and Drop and Data Transfer)>http://docs.oracle.com/javase/tutorial/uiswing/dnd/basicdemo.html
{
  private final DataFlavor localObjectFlavor;
  private JList source;
  private int[] indices;
  private int addIndex=-1;                                                     // Location where items were added
  private int addCount;                                                        // Number of items added.

  public ListItemTransferHandler()
  {
    super();
    localObjectFlavor=new ActivationDataFlavor(Object[].class,DataFlavor.javaJVMLocalObjectMimeType,"Array of items");
  }

  @Override protected Transferable createTransferable(JComponent c)
  {
    source=(JList)c;
    indices=source.getSelectedIndices();
    @SuppressWarnings("deprecation") Object[] transferedObjects=source.getSelectedValues();
    return new DataHandler(transferedObjects,localObjectFlavor.getMimeType());
  }

  @Override public boolean canImport(TransferSupport info) { return info.isDrop()&&info.isDataFlavorSupported(localObjectFlavor); }

  @Override public int getSourceActions(JComponent c)
  {
    return DemoDragAndDropListPanel.Copy_Button.isSelected()?COPY:MOVE;   // TransferHandler.COPY_OR_MOVE;
  }

  @SuppressWarnings("unchecked")
  @Override public boolean importData(TransferSupport info)
  {
    if (!canImport(info)) return false;
    TransferHandler.DropLocation tdl=info.getDropLocation();
    if (!(tdl instanceof JList.DropLocation)) return false;
    JList.DropLocation dl=(JList.DropLocation)tdl;
    JList target=(JList)info.getComponent();
    DefaultListModel listModel=(DefaultListModel)target.getModel();
    int index=dl.getIndex();
    //boolean insert = dl.isInsert();
    int max=listModel.getSize();
    if (index<0||index>max) index=max;
    addIndex=index;

    if ("songs-right-list".equals(target.getName()) && "play-left-list".equals(source.getName())) {
      System.out.println("[2] When I drag and drop an item from the left list to the right list, it only removes it from left list while does nothing to the right list");
      return true;
    }
    try
    {
      Object[] values=(Object[])info.getTransferable().getTransferData(localObjectFlavor);
      for (int i=0;i<values.length;i++)
      {
        int idx=index++;
        listModel.add(idx,values[i]);
        target.addSelectionInterval(idx,idx);
      }
      addCount=target.equals(source)?values.length:0;
      if ("play-left-list".equals(target.getName()) && "songs-right-list".equals(source.getName())) {
        System.out.println("[3] When I drag and drop an item from the right list to the left list, it only adds the item to the left list while does nothing to the right list.");
        indices = null;
      }
      return true;
    }
    catch (UnsupportedFlavorException|IOException ex) { ex.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)
    {
      // If we are moving items around in the same list, we need to adjust the indices accordingly, since those after the insertion point have moved.
      if (addCount>0)
      {
        for (int i=0;i<indices.length;i++) if (indices[i]>=addIndex) indices[i]+=addCount;
      }
      JList source=(JList)c;
      DefaultListModel model=(DefaultListModel)source.getModel();
      for (int i=indices.length-1;i>=0;i--) model.remove(indices[i]);
    }
    indices=null;
    addCount=0;
    addIndex=-1;
  }
}