2011-11-07 62 views
0

我试图让Java Applet中的模态框架如下所示:http://www.java2s.com/Tutorial/Java/0240__Swing/Showthegivenframeasmodaltothespecifiedowner.htm。这段代码有start()函数,看起来像java.lang.illegalArgumentException当使用反射调用pumpEvents

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 

你能告诉什么是错在这个调用以及如何避免此异常?

+0

__invoke__方法的第一个参数应该是要调用它的对象。在这里你传递__Thread.currentThread()__。那是对的吗?我宁愿使用__java.awt.EventDispatchThread__的实例来代替... – reef

+0

** @ reef **,谢谢你的回答。但我有另一个 - 我怎么能得到一个'java.awt.EventDispatchThread'的实例?再次使用反射? – GPAshka

+0

我解决了我的调用问题。原因在于线程类。我添加了获取java.awt.EventDispatchThread类的对象的代码,现在使用此对象调用invoke()metod:构造函数constructor = Class.forName(“java.awt.EventDispatchThread”)。 getDeclaredConstructor(ThreadGroup.class,name.getClass(),eventQueue.getClass()); 构造函数。setAccessible(真); 对象eventDispatchThread = constructor.newInstance(threadGroup,name,eventQueue);' – GPAshka

回答

1

这是什么意思是Thread.currentThread()返回的Thread对象不是EventDispatchThread的实例。

,以避免问题的方法是找出哪些对象的类确实是,并使用该获得Method对象。 (你应该能够找出它是通过打印你Thread.currentThread().getClass()获得在您试图调用该方法的地方对象是什么


invoke此的Javadoc这样说:。

“抛出IllegalArgumentException - 如果该方法是实例方法,并且指定的对象参数不是声明基础方法(或其子类或实现者)的类或接口的实例;如果实际参数和形式参数的数目不同;如果原始参数的展开转换失败;或者在可能的展开后, ameter价值无法通过方法调用转换而转换为相应的形参类型“。

我你的代码的解读是,你有实际参数的正确数目和类型,所以它必须与问题线程类。

0

AWT和swing GUI是单线程的事件派发线程是一个特殊的线程,所有的GUI操作都应该运行。很可能您的方法不会在GUI线程上调用。 Javadoc中不包含java.awt.EventDispatchThread所以你很可能要取决于一些实现细节:请确保您调用你的方法事件调度线程上,你可以通过调用它像这样

SwingUtilities.invokeAndWait(new Runnable(){public void run(){mymethod();}}) 

注意这样做。您可以使用java.awt.EventQueueToolkit.getSystemEventQueue()的子类。