Чтобы избежать "злобности" внутри каждого метода вашего класса, если ваш класс реализует открытый интерфейс, вы можете использовать Proxy
для выполнения общей настройки invokeAndWait
отдельно от где вы реализуете сами методы.
- Реализация прокси InvocationHandler , который будет обрабатывать весь стандартный код для проверки потока диспетчеризации событий и вызова
invokeAndWait
- Создайте экземпляр прокси и вызовите на нем методы, а не непосредственно в своем классе реализации.
Поскольку этот подход включает в себя больше кода в целом, он действительно подходит только в том случае, если в вашем классе реализации имеется большое количество методов, которые вы хотите обеспечить для выполнения в EDT.
Полный пример:
public class ImplClass implements ClassInterface {
public void a( String paramA, int paramB ) {
// do something here...
}
}
public interface ClassInterface {
void a( String paramA, int paramB );
}
public class MyHandler implements InvocationHandler {
private ClassInterface implClassInstance;
public MyHandler( ImplClass implInstance ) {
this.implClassInstance = implInstance;
}
public Object invoke( Object proxy, final Method method, final Object[] args ) throws Throwable {
if( SwingUtilities.isEventDispatchThread() ) {
method.invoke( implClassInstance, args );
}
else {
SwingUtilities.invokeAndWait( new Runnable() {
public void run() {
try {
method.invoke( implClassInstance, args );
}
catch( RuntimeException e ) {
throw e;
}
catch( Exception e ) {
throw new RuntimeException( e );
}
}
} );
}
return null;
}
}
Вот как бы вы использовали прокси:
// create the proxy like this:
ImplClass implInstance = new ImplClass();
MyHandler handler = new MyHandler(implInstance);
ClassInterface proxy = (ClassInterface) Proxy.newProxyInstance( this.getClass().getClassLoader(), new Class[] { ClassInterface.class }, handler );
// ...
// call the proxy like you would an instance of your implementation class
proxy.a( "paramAValue", 123 );