有没有办法在AWT / Swing中延迟(或流式传输)剪贴板操作?

时间:2016-02-25 03:04:41

标签: java swing awt clipboard

我有一张有一百万行的表。

如果我选择所有行和复制,则响应性返回GUI之前大约需要5分钟,之后我可以将其粘贴到另一个应用程序中。这不太好,所以我开始寻求改进。

如果我创建一个替代线程安全的TableModel,那么我可以后台构建字符串的操作,然后推送到剪贴板(如果需要,在EDT上)。然后GUI响应,但它仍然是我可以粘贴到另一个应用程序前5分钟,这在某些方面是一个更糟糕的体验,因为至少当它阻止EDT时,我能够告诉操作何时完成。我知道我可以为它添加GUI反馈,但对于像Copy这样的动作来说似乎是错误的。

如果我看一下本机应用程序之间发生的同样的事情,我注意到我可以毫不拖延地从一个应用程序中复制大量数据。然后我可以立即将它粘贴到另一个应用程序中,但没有任何延迟,但只是需要注意,所有信息最终会在那里停留很长时间。例如,如果我将TextEdit中的大文本粘贴到终端中,它似乎会以某种方式一次执行此操作。

在AWT中有没有办法做到这一点?

我尝试通过仅声明返回ReaderInputStream的替代风格来实现,但事实证明,即使你这样做,它也会向读者询问,读取读者然后立即读取整个流,将其存储为字符串。所以这只是将5分钟的延迟移动到JRE内部的代码中,什么也解决了。这也是相当愚蠢的,因为围绕您Transferable支持哪种类型的数据传输方法存在整个框架,但无论您公开哪种类型,系统似乎都将其转换为相同的类型,在最好的情况将需要永远建立,或者在最坏的情况下将使你失去堆。

也许有一种类型没有,所以我想我会发布这个问题,询问是否有人知道。

一个TransferHandler的示例,尽管JTable上的内置版本本身也存在同样的问题。

private class CombinedTransferHandler extends TransferHandler {
    @Override
    protected Transferable createTransferable(JComponent component) {
        if (component instanceof JTable) {
            JTable table = (JTable) component;

            int[] rows = table.getSelectedRows();
            if (!table.getRowSelectionAllowed()) {
                int rowCount = table.getRowCount();

                rows = new int[rowCount];
                for (int counter = 0; counter < rowCount; counter++) {
                    rows[counter] = counter;
                }
            }

            // columns omitted because we know we use all
            return new BasicTransferable(getPlainData(rows), null);
        }
        return null;
    }

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

    private String getPlainData(int[] rows) {
        StringBuilder result = new StringBuilder();

        int staticColumnCount = staticTable.getColumnCount();
        int mainColumnCount = mainTable.getColumnCount();
        for (int row : rows) {
            for (int viewColumn = 0; viewColumn < staticColumnCount;
                 viewColumn++) {
                if (viewColumn > 0) {
                    result.append('\t');
                }

                Object value = staticTable.getValueAt(row, viewColumn);
                value = (value == null) ? "" : value.toString();
                result.append(value);
            }

            for (int viewColumn = 0; viewColumn < mainColumnCount;
                 viewColumn++) {
                if (staticColumnCount > 0 || viewColumn > 0) {
                    result.append('\t');
                }

                Object value = mainTable.getValueAt(row, viewColumn);
                value = (value == null) ? "" : value.toString();
                result.append(value);
            }

            result.append('\n');
        }

        return result.toString();
    }
}

0 个答案:

没有答案