JTextArea - поддерживать функциональность буфера обмена после настройки TransferHandler - PullRequest
2 голосов
/ 21 марта 2012

Я следую примеру здесь , чтобы создать JTextArea, к которому я могу добавить объект и выполнить какое-либо действие.Это отлично работает.Моя проблема в том, что после установки TransferHandler с textArea.setTransferHandler (myTransferHandler) операции с буфером обмена, которые работают по умолчанию (вырезание, копирование и вставка текста), больше не работают.

Есть ли способ установить пользовательский TransferHandlerна моем JTextArea, чтобы включить перетаскивание объектов, но не мешать функциональности буфера обмена по умолчанию JTextArea?Если нет, то как проще всего изменить TransferHandler, чтобы обычные операции с буфером обмена продолжали работать в обычном режиме?

Обновление: вот пример, иллюстрирующий проблему.Я могу перетаскивать объекты из дерева в текстовую область, но функциональность буфера обмена в текстовой области нарушена.

import java.awt.GridLayout;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTree;
import javax.swing.TransferHandler;
import javax.swing.text.JTextComponent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeSelectionModel;

public class DnDTest
{
    public DnDTest()
    {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode(new NodeObject("root"));
        root.add(new DefaultMutableTreeNode(new NodeObject("child1")));
        root.add(new DefaultMutableTreeNode(new NodeObject("child2")));

        JTree tree = new JTree(new DefaultTreeModel(root));
        tree.setDragEnabled(true);
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

        JTextArea textArea = new JTextArea();
        textArea.setDragEnabled(true);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);

        NodeObjectTransferHandler transferHandler = new NodeObjectTransferHandler();
        tree.setTransferHandler(transferHandler);
        textArea.setTransferHandler(transferHandler);

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLayout(new GridLayout(1,0));
        f.add(new JScrollPane(tree));
        f.add(new JScrollPane(textArea));
        f.setSize(500,400);
        f.setLocation(200,200);
        f.setVisible(true);
    }

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

class NodeObject {
    public String str;

    public NodeObject(String str) { this.str = str; }
    @Override
    public String toString() { return str; }
}

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

    private static final DataFlavor nodeObjectFlavor = new DataFlavor(NodeObject.class, "NodeObject");

    @Override
    public boolean importData(JComponent c, Transferable t)
    {
        if (!canImport(c, t.getTransferDataFlavors())) {
            return false;
        }

        if (!(c instanceof JTextComponent)) {
            return false;
        }

        try {
            NodeObject nodeObject = (NodeObject) t.getTransferData(nodeObjectFlavor);
            ((JTextComponent) c).setText(nodeObject.str);
            return true;
        } catch (UnsupportedFlavorException e) {
        } catch (IOException e) {
        }

        return false;
    }

    @Override
    public Transferable createTransferable(JComponent c)
    {
        if (!(c instanceof JTree)) {
            return null;
        }

        JTree tree = (JTree) c;
        DefaultMutableTreeNode lastPathComponent = (DefaultMutableTreeNode) tree.getSelectionPath().getLastPathComponent();
        return new NodeObjectTransferable((NodeObject) lastPathComponent.getUserObject());
    }

    @Override
    public int getSourceActions(JComponent c)
    {
        return COPY;
    }

    @Override
    public boolean canImport(JComponent c, DataFlavor[] flavors)
    {
        for (DataFlavor flavor : flavors) {
            if (flavor.match(nodeObjectFlavor)) {
                return true;
            }
        }
        return false;
    }
}

class NodeObjectTransferable implements Transferable {
    private static final DataFlavor nodeObjectFlavor = new DataFlavor(NodeObject.class, "NodeObject");
    private NodeObject nodeObject;

    public NodeObjectTransferable(NodeObject nodeObject) {
        this.nodeObject = nodeObject;
    }

    @Override
    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
        if (!isDataFlavorSupported(flavor)) {
            throw new UnsupportedFlavorException(flavor);
        }

        return nodeObject;
    }

    @Override
    public DataFlavor[] getTransferDataFlavors()
    {
        return new DataFlavor[] { nodeObjectFlavor };
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor)
    {
        return flavor.match(nodeObjectFlavor);
    }
};
...