英文:
Cannot change Java Swing UI from Jsch's SftpProgressMonitor
问题
以下是翻译好的部分:
我想使用 `SftpProgressMonitor` 的 `count()` 方法来更新SFTP操作的完成百分比。我知道最好使用工作线程以避免阻塞用户界面,但我很好奇为什么这段代码在SFTP操作完成之前不会更新表格:
public class MySftpProgressMonitor implements SftpProgressMonitor {
JTable table = getTableReference();
DefaultTableModel tableModel = getTableModelReference();
@Override
public boolean count(long bytes) {
int percentage = computePercentage(bytes);
table.setValueAt(percentage, 0, 1);
return true;
}
@Override
public void end() {
}
@Override
public void init(int op, String src, String dest, long maxBytes) {
Object[] rowData = {src, 0};
tableModel.addRow(rowData);
}
}
我在用户界面上没有看到任何变化,直到文件传输完成(我看到一个百分比为100%的条目),我不知道为什么。由于我没有使用额外的线程,这段代码在EDT上执行,所以应该能够更新用户界面组件。我还尝试显式调用 repaint()
、table.repaint()
和 revalidate()
,但没有任何变化。
我正在阅读文档,但无法弄清楚这里的错误。谢谢。
英文:
I'd like to use SftpProgressMonitor
's count()
method to update the percentage of completion of a SFTP operation. I know it is better to use Worker threads in order not to block the UI, but I am curious on why this code does not update the table until the SFTP operation has completed:
public class MySftpProgressMonitor implements SftpProgressMonitor {
JTable table = getTableReference();
DefaultTableModel tableModel = getTableModelReference();
@Override
public boolean count(long bytes) {
int percentage = computePercentage(bytes);
table.setValueAt(percentage, 0, 1);
return true;
}
@Override
public void end() {
}
@Override
public void init(int op, String src, String dest, long maxBytes) {
Object[] rowData = {src, 0};
tableModel.addRow(rowData);
}
}
I don't see anything happening on the UI until the file transfer is completed (I see an entry whose percentage is 100%) and I wonder why. Since I am not using any additional threads, this code gets executed on the EDT, so it should be able to update UI components. I am also trying to explicitly call repaint()
, table.repaint()
and revalidate()
but nothing happens.
I am reading TFM but can't figure out what is the error here. Thank you.
答案1
得分: 0
这似乎是导致UI看起来冻结的主要原因,即使在事件分派线程上执行UI更改也是如此:
- 调用
table.setValueAt(percentage, 0, 1);
时,底层表格的结构会按预期进行修改并生成重绘请求; - 重绘请求由重绘管理器处理,负责在事件分派线程(EDT)变得空闲后执行,并按计划的顺序服务于重绘请求。
这意味着如果EDT不空闲,UI将不会被重绘。EDT不空闲是因为它正在处理SFTP传输。简单明了
英文:
For whoever might be interested, this appears to be the main reason on why the UI seems to be frozen even if the UI changes are performed on the Event Dispatch Thread:
- When calling
table.setValueAt(percentage, 0, 1);
the underlying table's structure gets modified as expected and generates a repaint request; - The repaint request gets handled by the repaint manager which is responsable for the repaint process and it is executed on the EDT after the EDT becomes idle, and serves the rapaint requests in the order they were scheduled.
This means that if the EDT is not idle, the UI will not be repainted. The EDT is not idle because it's processing a SFTP transfer. Easy
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论