我有一个普通的JTable和一个ListSelectionListener。我认为它可以正常工作,但有一个问题:
这会产生明显的延迟。
我可以更改活动的顺序吗?我想首先使用蓝色背景,然后执行http请求。 在valueChanged方法中插入睡眠定时器会使选择等到计时器结束。
答案 0 :(得分:1)
您应该在后台线程上执行HTTP请求。如果需要非常长的时间,这也有保持UI响应的优势。
根据您的实际需求,您最终会得到类似的代码:
private static class HttpWorker extends SwingWorker<Void, Void> {
private final String url;
private HttpWorker(String url) {
this.url = Objects.requireNonNull(url);
}
@Override
protected Void doInBackground() {
// do request, possibly producing some result
}
@Override
protected void done() {
if (!isCancelled()) {
// update UI
}
}
}
private HttpWorker worker;
@Override
public void valueChanged(ListSelectionEvent e) {
if (worker != null) {
// preserve apparent order of operations if
// the user selects something different while
// a background task is already running
worker.cancel(true);
worker = null;
}
worker = new HttpWorker(...);
worker.execute();
}
doInBackground
通常可以采取任何操作,只要您不与Swing UI进行交互。
另见the SwingWorker
tutorials和documentation。
为了获得完整的答案,在列表选择事件开始时执行以下操作可以
工作:jlist.paintImmediately(0, 0, jlist.getWidth(), jlist.getHeight());
至少在paintImmediately
被指定做隐含的事情的时候:
立即绘制此组件中指定区域及其与区域重叠的所有后代。 [...]如果需要在调度当前事件时更新显示,此方法很有用。
我不建议使用它的原因是没有特别的原因需要在我们自己的监听器之前更新JList
,这样列表实际上会绘制新的选择。
还有一个问题是,通常不应该在Swing线程上执行像HTTP请求这样的繁重任务,因为它会冻结UI。即使在您希望用户等待一段时间的情况下,也不会直接在Swing线程上执行任务。你可以在后台线程中执行它并弹出一个模态对话框,可能会让用户提前取消任务。