作为学习SwingWorker的一部分,我浏览了源代码,在其中发现了AccumulativeRunnable。从AccumulativeRunnable类定义的注释中,我知道何时使用它,但是当我检查示例代码时,我脑海中浮现出几个问题。
下面是AccumulativeRunnable抽象类中的注释和示例代码。
一个抽象类(AccumulativeRunnable),在需要对一组可附加数据执行某些操作的情况下使用。发送后,可能会追加数据集执行。通常将此类Runnable发送到EDT。
用法示例:说我们要实现JLabel.setText(String text)它将字符串发送到EDT上的JLabel.setTextImpl(String text)。如果JLabel.setText被EDT多次快速调用我们将在EDT上获得许多更新,但只有最后一个是重要。 (每个下一个更新都将覆盖上一个更新。)我们可能想要以仅最后一次更新为已交付。
AccumulativeRunnable<String> doSetTextImpl =
new AccumulativeRunnable<String>()} {
protected void run(List<String> args)} {
//set to the last string being passed
setTextImpl(args.get(args.size() - 1));
}
}
void setText(String text) {
//add text and send for the execution if needed.
doSetTextImpl.add(text);
}
implements
Runnable
。这意味着AccumulativeRunnable类应该实现运行方法对吗?但是我只能看到protected abstract void
run(List<T> args);
。这如何实现Runnable
界面。add()
方法是synchronized
?有人可以用一个简单的例子来解释这一点吗?我上面提供的示例。arguments
方法中的add()
AccumulativeRunnable类将为null
?有人可以用一个简单的例子来解释这一点吗?我上面提供的示例。add()
方法如何接收数组(T ... args)?有人可以吗用一个简单的例子或我提供的例子来解释以上。doSetTextImpl.add(text);
调用AccumulativeRunnable类的add()
方法。但是这怎么内部调用run()
方法?我的意思是谁在打电话给我们内部实现了run()
方法。public abstract class AccumulativeRunnable<T> implements Runnable {
private List<T> arguments = null;
/**
* Equivalent to {@code Runnable.run} method with the
* accumulated arguments to process.
*
* @param args accumulated argumets to process.
*/
protected abstract void run(List<T> args);
/**
* {@inheritDoc}
*
* <p>
* This implementation calls {@code run(List<T> args)} mehtod
* with the list of accumulated arguments.
*/
public final void run() {
run(flush());
}
/**
* appends arguments and sends this {@code Runnable} for the
* execution if needed.
* <p>
* This implementation uses {@see #submit} to send this
* {@code Runnable} for execution.
* @param args the arguments to accumulate
*/
@SafeVarargs
@SuppressWarnings("varargs") // Copying args is safe
public final synchronized void add(T... args) {
boolean isSubmitted = true;
if (arguments == null) {
isSubmitted = false;
arguments = new ArrayList<T>();
}
Collections.addAll(arguments, args);
if (!isSubmitted) {
submit();
}
}
/**
* Sends this {@code Runnable} for the execution
*
* <p>
* This method is to be executed only from {@code add} method.
*
* <p>
* This implementation uses {@code SwingWorker.invokeLater}.
*/
protected void submit() {
SwingUtilities.invokeLater(this);
}
/**
* Returns accumulated arguments and flashes the arguments storage.
*
* @return accumulated arguments
*/
private synchronized List<T> flush() {
List<T> list = arguments;
arguments = null;
return list;
}
}
答案是Runnable.run()
的以下实现。从编译器的角度来看,run(List<T>)
与接口声明的方法无关,它只是名称相同(巧合)的另一种方法。