使用拖放重新排序 JList

编程入门 行业动态 更新时间:2024-10-26 20:34:39
本文介绍了使用拖放重新排序 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.抱歉,如果这是一个重新发布.

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.BorderLayout; import java.awt.Component; import java.awt.EventQueue; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.Transferable; import java.awt.datatransfer.UnsupportedFlavorException; import java.awt.dnd.DragSource; import java.io.IOException; import java.io.Serializable; import java.util.Arrays; import java.util.Objects; // import javax.activation.ActivationDataFlavor; // import javax.activation.DataHandler; import javax.swing.BorderFactory; import javax.swing.DefaultListModel; import javax.swing.DropMode; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListCellRenderer; import javax.swing.ListSelectionModel; import javax.swing.TransferHandler; import javax.swing.UIManager; import javax.swing.WindowConstants; 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); // java-swing-tips.blogspot/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<? extends Thumbnail> 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(() -> 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 implements Serializable { 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. // docs.oracle/javase/tutorial/uiswing/dnd/dropmodedemo.html @SuppressWarnings("serial") class ListItemTransferHandler extends TransferHandler { protected final DataFlavor localObjectFlavor; protected int[] indices; protected int addIndex = -1; // Location where items were added protected int addCount; // Number of items added. public ListItemTransferHandler() { super(); // localObjectFlavor = new ActivationDataFlavor( // Object[].class, DataFlavor.javaJVMLocalObjectMimeType, "Array of items"); localObjectFlavor = new DataFlavor(Object[].class, "Array of items"); } @Override protected Transferable createTransferable(JComponent c) { JList<?> source = (JList<?>) c; c.getRootPane().getGlassPane().setVisible(true); indices = source.getSelectedIndices(); Object[] transferedObjects = source.getSelectedValuesList().toArray(new Object[0]); // return new DataHandler(transferedObjects, localObjectFlavor.getMimeType()); return new Transferable() { @Override public DataFlavor[] getTransferDataFlavors() { return new DataFlavor[] {localObjectFlavor}; } @Override public boolean isDataFlavorSupported(DataFlavor flavor) { return Objects.equals(localObjectFlavor, flavor); } @Override public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException { if (isDataFlavorSupported(flavor)) { return transferedObjects; } else { throw new UnsupportedFlavorException(flavor); } } }; } @Override public boolean canImport(TransferSupport info) { return info.isDrop() && info.isDataFlavorSupported(localObjectFlavor); } @Override public int getSourceActions(JComponent c) { Component glassPane = c.getRootPane().getGlassPane(); glassPane.setCursor(DragSource.DefaultMoveDrop); return MOVE; // COPY_OR_MOVE; } @SuppressWarnings("unchecked") @Override public boolean importData(TransferSupport info) { TransferHandler.DropLocation tdl = info.getDropLocation(); if (!canImport(info) || !(tdl instanceof JList.DropLocation)) { return false; } JList.DropLocation dl = (JList.DropLocation) tdl; JList target = (JList) info.getComponent(); DefaultListModel listModel = (DefaultListModel) target.getModel(); int max = listModel.getSize(); int index = dl.getIndex(); index = index < 0 ? max : index; // If it is out of range, it is appended to the end index = Math.min(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 = values.length; return true; } catch (UnsupportedFlavorException | IOException ex) { ex.printStackTrace(); } return false; } @Override protected void exportDone(JComponent c, Transferable data, int action) { c.getRootPane().getGlassPane().setVisible(false); cleanup(c, action == MOVE); } private void cleanup(JComponent c, boolean remove) { if (remove && Objects.nonNull(indices)) { if (addCount > 0) { // github/aterai/java-swing-tips/blob/master/DragSelectDropReordering/src/java/example/MainPanel.java 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; } }

更多推荐

使用拖放重新排序 JList

本文发布于:2023-08-06 05:11:26,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1310268.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:拖放   JList

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!