【问题标题】:Java drag and drop images in a listJava在列表中拖放图像
【发布时间】:2011-11-05 14:00:47
【问题描述】:

我正在寻找一种方法来以水平顺序显示一系列图片(带有图像的 JPanel,可能还有其他一些小组件)。

用户应该能够通过拖放重新排列图像的顺序。 我该怎么做呢?带有一些自定义组件和 D&D 的 JList 是要走的路吗? 一些需要考虑的问题(我听说让组件具有相同的尺寸会提高性能)。

【问题讨论】:

    标签: java image swing drag-and-drop jlist


    【解决方案1】:

    以下示例向您展示如何在列表中水平显示图像并使用拖放重新排列它们。如果空间不足,列表将水平换行。

    import javax.swing.*;
    import javax.swing.border.Border;
    import java.awt.*;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.Transferable;
    import java.awt.datatransfer.UnsupportedFlavorException;
    import java.io.IOException;
    import java.io.Serializable;
    
    public class ImagePreviewListTest {
    
        public static void main(String[] args) throws Exception {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            JFrame frame = new JFrame("Image panel");
            frame.setSize(800, 300);
            frame.setLocationByPlatform(true);
            JList imageList = createImageList();
            frame.getContentPane().add(new JScrollPane(imageList));
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    
        private static JList createImageList() {
    
            JList imageList = new JList(createModel());
            imageList.setCellRenderer(new ImageCellRenderer());
            imageList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
            imageList.setVisibleRowCount(-1);
            imageList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            imageList.setFixedCellWidth(240);
            imageList.setFixedCellHeight(120);
    
            imageList.setDragEnabled(true);
            imageList.setDropMode(DropMode.INSERT);
            imageList.setTransferHandler(new ImageTransferHandler(imageList));
    
            return imageList;
    }
    
        private static DefaultListModel createModel() {
            DefaultListModel model = new DefaultListModel();
            model.addElement(new ColorIcon(Color.RED));
            model.addElement(new ColorIcon(Color.GREEN));
            model.addElement(new ColorIcon(Color.BLACK));
            model.addElement(new ColorIcon(Color.BLUE));
            model.addElement(new ColorIcon(Color.MAGENTA));
            model.addElement(new ColorIcon(Color.PINK));
            model.addElement(new ColorIcon(Color.YELLOW));
            model.addElement(new ColorIcon(Color.ORANGE));
            return model;
        }
    
        static class ImageTransferHandler extends TransferHandler {
    
            private static final DataFlavor DATA_FLAVOUR = new DataFlavor(ColorIcon.class, "Images");
    
            private final JList previewList;
            private boolean inDrag;
    
            ImageTransferHandler(JList previewList) {
                this.previewList = previewList;
            }
    
            public int getSourceActions(JComponent c) {
                return TransferHandler.MOVE;
            }
    
            protected Transferable createTransferable(JComponent c) {
                inDrag = true;
                return new Transferable() {
                    public DataFlavor[] getTransferDataFlavors() {
                        return new DataFlavor[] {DATA_FLAVOUR};
                    }
    
                    public boolean isDataFlavorSupported(DataFlavor flavor) {
                        return flavor.equals(DATA_FLAVOUR);
                    }
    
                    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
                        return previewList.getSelectedValue();
                    }
                };
            }
    
            public boolean canImport(TransferSupport support) {
                if (!inDrag || !support.isDataFlavorSupported(DATA_FLAVOUR)) {
                    return false;
                }
    
                JList.DropLocation dl = (JList.DropLocation)support.getDropLocation();
                if (dl.getIndex() == -1) {
                    return false;
                } else {
                    return true;
                }
            }
    
            public boolean importData(TransferSupport support) {
                if (!canImport(support)) {
                    return false;
                }
    
                Transferable transferable = support.getTransferable();
                try {
                    Object draggedImage = transferable.getTransferData(DATA_FLAVOUR);
    
                    JList.DropLocation dl = (JList.DropLocation)support.getDropLocation();
                    DefaultListModel model = (DefaultListModel)previewList.getModel();
                    int dropIndex = dl.getIndex();
                    if (model.indexOf(draggedImage) < dropIndex) {
                        dropIndex--;
                    }
                    model.removeElement(draggedImage);
                    model.add(dropIndex, draggedImage);
                    return true;
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }
            }
    
            protected void exportDone(JComponent source, Transferable data, int action) {
                super.exportDone(source, data, action);
                inDrag = false;
            }
        }
    
        static class ImageCellRenderer extends JPanel implements ListCellRenderer {
    
            DefaultListCellRenderer defaultListCellRenderer = new DefaultListCellRenderer();
            JLabel imageLabel = new JLabel();
            JLabel descriptionLabel = new JLabel();
    
            ImageCellRenderer() {
                setLayout(new BorderLayout());
                Border emptyBorder = BorderFactory.createEmptyBorder(5, 5, 5, 5);
                imageLabel.setBorder(emptyBorder);
                descriptionLabel.setBorder(emptyBorder);
                add(imageLabel, BorderLayout.CENTER);
                add(descriptionLabel, BorderLayout.SOUTH);
            }
    
            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                defaultListCellRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                setBorder(defaultListCellRenderer.getBorder());
                setBackground(defaultListCellRenderer.getBackground());
                imageLabel.setIcon((Icon)value);
                descriptionLabel.setText("Description");
                return this;
            }
        }
    
        static class ColorIcon implements Icon, Serializable {
            private Color color;
    
            ColorIcon(Color color) {
                this.color = color;
            }
    
            public void paintIcon(Component c, Graphics g, int x, int y) {
                g.setColor(color);
                g.fillRect(x, y, getIconWidth(), getIconHeight());
            }
    
            public int getIconWidth() {
                return 200;
            }
    
            public int getIconHeight() {
                return 100;
            }
    
            public boolean equals(Object o) {
                if (o == null || getClass() != o.getClass()) {
                    return false;
                }
                return color.equals(((ColorIcon)o).color);
            }
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      【讨论】:

        【解决方案3】:

        创建一个包含图像的 ListModel。

        创建一个显示它们的 ListCellRenderer 并将其设置为 List 的渲染器。您可以在渲染器中使用 JLabel,以便轻松设置图像。

        创建一个知道如何处理 DataFlavor.imageFlavor 的 TransferHandler。 StanislavL 引用的例子是一个开始。

        设置列表的 transferHandler 属性。

        【讨论】:

          猜你喜欢
          • 2011-08-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多