我正在尝试在Java Applet中制作模态框架,如下所示:http://www.java2s.com/Tutorial/Java/0240__Swing/Showthegivenframeasmodaltothespecifiedowner.htm。这段代码有start()函数,看起来像
public void start() throws Exception {
Class<?> clazz = Class.forName("java.awt.Conditional");
Object conditional = Proxy.newProxyInstance(clazz.getClassLoader(), new Class[] { clazz },
this);
Method pumpMethod = Class.forName("java.awt.EventDispatchThread").getDeclaredMethod(
"pumpEvents", new Class[] { clazz });
pumpMethod.setAccessible(true);
pumpMethod.invoke(Thread.currentThread(), new Object[] { conditional });
}.
当我呼叫
pumpMethod.invoke(Thread.currentThread(), new Object[] { conditional });
我有以下例外:
java.lang.RuntimeException: java.lang.IllegalArgumentException: object is not an instance of declaring class
at wizard.ModalFrameUtil.showAsModal(ModalFrameUtil.java:136)
at wizard.WizardCore.showWizardFrame(WizardCore.java:206)
at SelfRegistrationApplet$1.run(SelfRegistrationApplet.java:55)
at SelfRegistrationApplet$1.run(SelfRegistrationApplet.java:35)
at java.security.AccessController.doPrivileged(Native Method)
at SelfRegistrationApplet.RunSelfRegistrationApplet(SelfRegistrationApplet.java:32)
at SelfRegistrationApplet.init(SelfRegistrationApplet.java:26)
at sun.applet.AppletPanel.run(AppletPanel.java:424)
at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.IllegalArgumentException: object is not an instance of declaring class
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at wizard.ModalFrameUtil$EventPump.start(ModalFrameUtil.java:80)
at wizard.ModalFrameUtil.showAsModal(ModalFrameUtil.java:133)
... 8 more
你能告诉我这个调用有什么问题以及如何避免这个异常吗?
意思是Thread.currentThread()
返回的Thread
对象不是EventDispatchThread
的实例。
Method
对象。(您应该能够通过在您试图调用该方法的地方打印从Thread.currentThread().getClass()
获得的对象来找出它是什么。
invoke
的Javadoc是这样说的:
"抛出
IllegalArgumentException
-如果方法是一个实例方法,并且指定的对象参数不是声明底层方法的类或接口的实例(或子类或其实现);如果实际参数和形式参数的数量不同;如果原始参数的展开转换失败;或者,在可能展开后,参数值无法通过方法调用转换转换为相应的形式参数类型。"
我对你的代码的阅读是,你有正确的数量和类型的实际参数,所以它必须与线程类的问题。
AWT和swing GUI是单线程的,事件调度线程是一个特殊的线程,所有GUI操作都应该在其中运行。很可能您的方法没有在GUI线程上调用。确保在事件分派线程上调用方法,您可以这样调用它
SwingUtilities.invokeAndWait(new Runnable(){public void run(){mymethod();}})
注意:javadocs不包含java.awt.EventDispatchThread
,所以您可能依赖于一些实现细节。您可以使用java.awt.EventQueue
和Toolkit.getSystemEventQueue()
的子类来代替。