代码之家  ›  专栏  ›  技术社区  ›  Matthias Braun AdamSkywalker

Swing-drag映像在Linux上不起作用

  •  1
  • Matthias Braun AdamSkywalker  · 技术社区  · 6 年前

    我注意到使用 setDragImage JList 的拖放支持适用于Windows10Professionalx86,而在ArchLinux4.17.5和XFCE上则不适用。

    明显的区别:

    在Windows上拖动图像

    Drag and Drop on Window

    Drag and Drop on Linux

    起初,我怀疑这可能是由于不同的JDK版本造成的问题:Windows上的OracleJDK和Linux上的OpenJDK,都是1.8.0哏172版本。

    但我换成 Oracle JDK 1.8.0_172 on Arch Linux .

    在Linux上使用IntelliJ进行调试时,我可以看到拖动图像的创建方式与 BufferedImage 列表框 的元素,但调用 定位符 似乎对Linux没有任何影响。

    以下重现此问题的代码是 aterai's answer here :

    import javax.swing.*;
    import java.awt.*;
    import java.awt.datatransfer.DataFlavor;
    import java.awt.datatransfer.StringSelection;
    import java.awt.datatransfer.Transferable;
    import java.awt.image.BufferedImage;
    import java.util.List;
    
    // From https://stackoverflow.com/questions/11437402/setdragimage-not-working-java-7#11448623
    public class BasicDnd {
    
        private static void createAndShowGUI() {
            JFrame f = new JFrame("BasicDnD");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setContentPane(new BasicDnd().makeUI());
            f.setSize(320, 320);
            f.setLocationRelativeTo(null);
            f.setVisible(true);
        }
    
        public static void main(String[] args) {
            printJavaInfo();
            EventQueue.invokeLater(BasicDnd::createAndShowGUI);
        }
    
        private static void printJavaInfo() {
            Package runtimePackage = Runtime.class.getPackage();
            String specVendor = runtimePackage.getSpecificationVendor();
            String implementationVendor = runtimePackage.getImplementationVendor();
            String version = runtimePackage.getImplementationVersion();
            System.out.println("Specification vendor: " + specVendor);
            System.out.println("Implementation vendor: " + implementationVendor);
            System.out.println("JRE version: " + version);
        }
    
        private JList makeList() {
            DefaultListModel<String> m = new DefaultListModel<>();
            m.addElement("Martha Washington");
            m.addElement("Abigail Adams");
            m.addElement("Martha Randolph");
            JList<String> list = new JList<>(m);
            list.setTransferHandler(new TransferHandler() {
                private final JPanel p = new JPanel();
                private BufferedImage bufferedImage;
                private int width, height;
    
                @Override
                public boolean canImport(TransferHandler.TransferSupport info) {
                    if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                        return false;
                    }
                    JList.DropLocation dl = (JList.DropLocation) info.getDropLocation();
                    return dl.getIndex() != -1;
                }
    
                @Override
                public int getSourceActions(JComponent c) {
                    BufferedImage img = makeImageFromString(c);
                    if (img != null) {
                        setDragImage(img);
                    }
                    return COPY;
                }
    
                private BufferedImage makeImageFromString(JComponent src) {
                    JList l = (JList) src;
                    int idx = l.getSelectedIndex();
                    Rectangle rect = list.getCellBounds(idx, idx);
                    if (rect == null) return null;
                    if (bufferedImage == null || rect.width != width || rect.height != height) {
                        width = rect.width;
                        height = rect.height;
                        bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
                    }
                    Component c = l.getCellRenderer().getListCellRendererComponent(
                            l, l.getSelectedValue(), idx, false, false);
                    Graphics g = bufferedImage.getGraphics();
                    g.clearRect(0, 0, width, height);
                    SwingUtilities.paintComponent(g, c, p, 0, 0, width, height);
                    g.dispose();
                    return bufferedImage;
                }
    
                @Override
                protected Transferable createTransferable(JComponent c) {
                    JList list = (JList) c;
                    List values = list.getSelectedValuesList();
                    StringBuilder buff = new StringBuilder();
                    for (int i = 0; i < values.size(); i++) {
                        Object val = values.get(i);
                        buff.append(val == null ? "" : val.toString());
                        if (i != values.size() - 1) {
                            buff.append("\n");
                        }
                    }
                    return new StringSelection(buff.toString());
                }
            });
            list.setDropMode(DropMode.ON_OR_INSERT);
            list.setDragEnabled(true);
            return list;
        }
    
        private JComponent makeUI() {
            JPanel panel = new JPanel(new GridLayout(2, 1));
            JTextArea textArea = new JTextArea("Drag here from JList!");
            panel.add(new JScrollPane(textArea));
            panel.add(new JScrollPane(makeList()));
            return panel;
        }
    }
    

    0 回复  |  直到 6 年前