4

我正在实现将 JLabels 的 Textattribute 拖放到 JTable 的单元格中的功能。所以我为表创建了一个自定义的 TransferHandler。但每一次的呼唤

support.isDataFlavorSupported(DataFlavor.stringFlavor) 

返回假

如何确保我的 TransferHandler 能够导入字符串?

这里是源

public class TableHandler extends TransferHandler {
    private static final long serialVersionUID = 1L;

@Override
public boolean canImport(TransferSupport support) {
    if (!support.isDrop()) {
        return false;
    }
    //only Strings
    if(!support.isDataFlavorSupported(DataFlavor.stringFlavor)){
        return false;
    }
    return true;
}

@Override
public boolean importData(TransferSupport support) {
    if (!canImport(support)) {
        return false;
    }

    Transferable tansferable = support.getTransferable();
    String line;
    try {
        line = (String) tansferable
                .getTransferData(DataFlavor.stringFlavor);
    } catch (Exception e) {
        return false;
    }

    JTable.DropLocation dl = (JTable.DropLocation) support
            .getDropLocation();
    int column = dl.getColumn();
    int row = dl.getRow();

    String[] data = line.split(",");
    for (String item : data) {
        if (!item.isEmpty()) {
            table.getTableModel().setValueAt(item, row, column);
        }
    }
    return true;
}
}
4

2 回答 2

5

检查这个例子似乎工作正常:

在任何拖放JLabels 之前:

在此处输入图像描述

单击并将Hello 拖动JLabel到第一个单元格:

在此处输入图像描述

释放单击第一个单元格时:

在此处输入图像描述

import java.awt.BorderLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.io.IOException;
import javax.swing.DropMode;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;

public class Test {

    public static void main(String[] args) {
        createAndShowJFrame();
    }

    public static void createAndShowJFrame() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {

                JFrame frame = createJFrame();
                frame.setVisible(true);

            }
        });
    }

    private static JFrame createJFrame() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setTitle("Test");

        JTable table = createJTable();
        JScrollPane js = new JScrollPane(table);

        frame.add(js, BorderLayout.CENTER);

        frame.add(createJLabelPanel(), BorderLayout.SOUTH);

        frame.pack();

        //frame.setResizable(false);//make it un-resizeable
        //frame.setLocationRelativeTo(null);//center JFrame

        return frame;
    }

    private static JTable createJTable() {
        // setup table data
        String[] columns = new String[]{"Foo", "Bar", "Baz", "Quux"};
        String[][] data = new String[][]{{"A", "B", "C", "D"},
            {"1", "2", "3", "4"},
            {"i", "ii", "iii", "iv"}};
        // create table
        final JTable table = new JTable(data, columns);

        // set up drag and drop
        table.setDragEnabled(true);
        table.setDropMode(DropMode.USE_SELECTION);
        table.setFillsViewportHeight(true);

        TransferHandler dnd = new TransferHandler() {
            @Override
            public boolean canImport(TransferSupport support) {
                if (!support.isDrop()) {
                    return false;
                }
                //only Strings
                if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) {
                    return false;
                }
                return true;
            }

            @Override
            public boolean importData(TransferSupport support) {
                if (!canImport(support)) {
                    return false;
                }

                Transferable tansferable = support.getTransferable();
                String line;
                try {
                    line = (String) tansferable.getTransferData(DataFlavor.stringFlavor);
                } catch (Exception e) {
                    e.printStackTrace();
                    return false;
                }

                JTable.DropLocation dl = (JTable.DropLocation) support.getDropLocation();
                int column = dl.getColumn();
                int row = dl.getRow();

                String[] data = line.split(",");
                for (String item : data) {
                    if (!item.isEmpty()) {
                        table.getModel().setValueAt(item, row, column);
                    }
                }
                return true;
            }
        };
        table.setTransferHandler(dnd);
        table.setPreferredScrollableViewportSize(table.getPreferredSize());
        return table;
    }

    private static JPanel createJLabelPanel() {
        JPanel panel = new JPanel();
        JLabel label1 = new JLabel("Hello");
        JLabel label2 = new JLabel("Yay");
        JLabel label3 = new JLabel("Bye");

        MyDragGestureListener dlistener = new MyDragGestureListener();
        DragSource ds1 = new DragSource();
        ds1.createDefaultDragGestureRecognizer(label1, DnDConstants.ACTION_COPY, dlistener);

        DragSource ds2 = new DragSource();
        ds2.createDefaultDragGestureRecognizer(label2, DnDConstants.ACTION_COPY, dlistener);

        DragSource ds3 = new DragSource();
        ds3.createDefaultDragGestureRecognizer(label3, DnDConstants.ACTION_COPY, dlistener);

        panel.add(label1);
        panel.add(label2);
        panel.add(label3);
        return panel;
    }
}

class MyDragGestureListener implements DragGestureListener {

    @Override
    public void dragGestureRecognized(DragGestureEvent event) {
        JLabel label = (JLabel) event.getComponent();
        final String text = label.getText();


        Transferable transferable = new Transferable() {
            @Override
            public DataFlavor[] getTransferDataFlavors() {
                return new DataFlavor[]{DataFlavor.stringFlavor};
            }

            @Override
            public boolean isDataFlavorSupported(DataFlavor flavor) {
                if (!isDataFlavorSupported(flavor)) {
                    return false;
                }
                return true;
            }

            @Override
            public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
                return text;
            }
        };
        event.startDrag(null, transferable);
    }
}
于 2013-06-25T13:47:33.647 回答
1

David 的低级方法(用于从标签上拖出)的更高级别的替代方法是在其上使用 in-build 属性传输。只需设置 transferHandler 和触发导出的 mouseListener 即可安装它:

MouseListener listener = new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent e) {
        JComponent c = (JComponent) e.getSource();
        TransferHandler handler = c.getTransferHandler();
        handler.exportAsDrag(c, e, TransferHandler.COPY);
    }
};
// a transferHandler configured to export the text property
TransferHandler handler = new TransferHandler("text");
JComponent labels = new JPanel();
for (int i = 0; i < 4; i++) {
    JLabel label1 = new JLabel("item: " + i);
    label1.addMouseListener(listener);
    label1.setTransferHandler(handler);
    labels.add(label1);
}

付出的代价是 TableTransferHandler 中的工作稍微多一些:它现在不仅要检查预定义的 stringFlavor,还要检查表示类和 String 并接受它:

public class TableHandlerExt extends TransferHandler {

    /**
     * Implemented to return true if the support can provide string values.
     */
    @Override
    public boolean canImport(TransferSupport support) {
        if (!support.isDrop()) {
            return false;
        }
        return isStringDataSupported(support);
    }

    /**
     * Returns a boolean indicating whether or not the support can
     * provide a string value. Checks for predefined DataFlavor.stringFlavor
     * and flavors with a representationClass of String.
     */
    protected boolean isStringDataSupported(TransferSupport support) {
        if (support.isDataFlavorSupported(DataFlavor.stringFlavor)) return true;
        DataFlavor[] flavors = support.getDataFlavors();
        for (DataFlavor dataFlavor : flavors) {
            if (dataFlavor.getRepresentationClass() == String.class) return true;
        }
        return false;
    }

    @Override
    public boolean importData(TransferSupport support) {
        if (!canImport(support)) {
            return false;
        }

        String line;
        try {
            line = getStringData(support);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        JTable table = (JTable) support.getComponent();
        JTable.DropLocation dl = (JTable.DropLocation) support.getDropLocation();
        int column = dl.getColumn();
        int row = dl.getRow();

        if (!line.isEmpty()) {
            // note: we need to use table api to access the table, as the 
            // row/column coordinates are view coordinates
            table.setValueAt(line, row, column);
        }
        return true;
    }

    /**
     * Returns the String provided by the support. 
     * Tries for predefined DataFlavor.stringFlavor
     * and flavors with a representationClass of String.            
     */
    protected String getStringData(TransferSupport support) 
        throws UnsupportedFlavorException, IOException {
        if (support.isDataFlavorSupported(DataFlavor.stringFlavor)) {
            return (String) support.getTransferable().getTransferData(DataFlavor.stringFlavor);
        }
        DataFlavor[] flavors = support.getDataFlavors();
        for (DataFlavor dataFlavor : flavors) {
            if (dataFlavor.getRepresentationClass() == String.class) {
                return (String) support.getTransferable().getTransferData(dataFlavor);
            }
        }
        return "";
    }

}
于 2013-06-25T16:16:47.653 回答