如何在SWT / Swing中收集频繁的更新/重绘/布局/刷新操作?

时间:2014-02-25 19:05:52

标签: java multithreading swing event-handling swt

我正在做一些频繁的操作,这需要GUI刷新(将一些子项添加到控件中)。

我无法控制整个添加完成的那一刻,所以我不能在最后进行更新/重绘/布局/刷新,并且每一步都需要这样做。

同时我需要经常点头,因为用户不需要看到每个变化。

每次更新/重绘/布局/刷新都会减慢进程。

所以,我需要决定是否按时更新/重绘/布局/刷新。

我为SWT编写了以下通用类,但类似的也适用于Swing。

这是逻辑完整和正确吗?特别是,检查delayedMap.get(doRun) == timer是否可以在多线程中正常工作?如果在invokeOnceDelayed()TimerTask.run()块的输入之间输入synchronized方法,则取消延迟操作的目的是什么?

public class SWTUtilities {

    private static HashMap<Runnable, Timer> delayedMap = new HashMap<Runnable, Timer>();

    public static void invokeLater(Runnable doRun) {
        Display.getDefault().asyncExec(doRun);
    }

    public static void invokeAndWait(Runnable doRun) {
        Display.getDefault().syncExec(doRun);
    }

    public static synchronized void invokeOnceDelayed(final Runnable doRun, long delay) {

        final Timer timer = new Timer(true);
        Timer oldTimer = delayedMap.put(doRun, timer);
        if( oldTimer != null ) {
            oldTimer.cancel();
        }

        timer.schedule(new TimerTask() {

            @Override
            public void run() {
                synchronized(SWTUtilities.class) {
                    if( delayedMap.get(doRun) == timer ) {
                        invokeLater(doRun);
                    }
                }

            }}, delay);


    }

}

1 个答案:

答案 0 :(得分:0)

您可以直接委托Display.timerExec来实现invokeOnceDelayed()方法。