Java ListSelectionListener事件中的延迟

Java ListSelectionListener事件中的延迟,java,jtable,delay,listselectionlistener,Java,Jtable,Delay,Listselectionlistener,我有一个普通的JTable和一个ListSelectionListener。我想这是应该的,但有一个问题: 我点击一个表格行 事件激发(方法valueChanged生效) 在valueChanged内部,我启动一个http请求(需要几毫秒) 表格行被明显选中(蓝色背景) 这会产生明显的延迟 我可以更改活动的顺序吗?我想先使用蓝色背景,然后执行http请求。 在valueChanged方法中插入睡眠计时器会使选择等待计时器完成。您可能应该在后台线程上执行HTTP请求。如果需要异常长的时间,这还具有

我有一个普通的JTable和一个ListSelectionListener。我想这是应该的,但有一个问题:

  • 我点击一个表格行
  • 事件激发(方法valueChanged生效)
  • 在valueChanged内部,我启动一个http请求(需要几毫秒)
  • 表格行被明显选中(蓝色背景)
  • 这会产生明显的延迟

    我可以更改活动的顺序吗?我想先使用蓝色背景,然后执行http请求。
    在valueChanged方法中插入睡眠计时器会使选择等待计时器完成。

    您可能应该在后台线程上执行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();
    }
    
    这至少是规定要做的事情:

    立即绘制此组件中的指定区域及其与该区域重叠的所有子体。[…]如果在调度当前事件时需要更新显示,则此方法非常有用

    我不建议使用它的原因是,没有特别的原因需要在我们自己的侦听器之前更新
    JList
    ,以便列表实际绘制新的选择


    还有一个问题是,像HTTP请求这样的繁重任务通常不应该在Swing线程上完成,因为它会冻结UI。即使在希望用户等待一段时间的情况下,也不会直接在Swing线程上执行任务。您可以在后台线程中执行此操作,并弹出一个模式对话框,可能会给用户提前取消任务的选项。

    感谢您的快速回复。我已经考虑过做一个背景线程,但对于这样一个简单的任务,这对我来说似乎有点奇怪。我通常对选择顺序的想法是:“选择表行,java将其标记为蓝色,fire valueChanged”。请参阅我的编辑以了解替代方法,并讨论为什么使用后台线程实际上更好。
    jlist.paintImmediately(0, 0, jlist.getWidth(), jlist.getHeight());