我有一张有一百万行的表。
如果我选择所有行和复制,则响应性返回GUI之前大约需要5分钟,之后我可以将其粘贴到另一个应用程序中。这不太好,所以我开始寻求改进。
如果我创建一个替代线程安全的TableModel,那么我可以后台构建字符串的操作,然后推送到剪贴板(如果需要,在EDT上)。然后GUI响应,但它仍然是我可以粘贴到另一个应用程序前5分钟,这在某些方面是一个更糟糕的体验,因为至少当它阻止EDT时,我能够告诉操作何时完成。我知道我可以为它添加GUI反馈,但对于像Copy这样的动作来说似乎是错误的。
如果我看一下本机应用程序之间发生的同样的事情,我注意到我可以毫不拖延地从一个应用程序中复制大量数据。然后我可以立即将它粘贴到另一个应用程序中,但没有任何延迟,但只是需要注意,所有信息最终会在那里停留很长时间。例如,如果我将TextEdit中的大文本粘贴到终端中,它似乎会以某种方式一次执行此操作。
在AWT中有没有办法做到这一点?
我尝试通过仅声明返回Reader
和InputStream
的替代风格来实现,但事实证明,即使你这样做,它也会向读者询问,读取读者然后立即读取整个流,将其存储为字符串。所以这只是将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();
}
}