-
FEATURED COMPONENTS
First time here? Check out the FAQ!
hai,
need a solution for this error
Exception in thread "Thread-34" java.lang.IllegalStateException: Components can be accessed only in event listeners
at org.zkoss.zk.ui.impl.UiEngineImpl.getCurrentVisualizer(UiEngineImpl.java:233)
at org.zkoss.zk.ui.impl.UiEngineImpl.addInvalidate(UiEngineImpl.java:253)
at org.zkoss.zk.ui.AbstractComponent.invalidate(AbstractComponent.java:1106)
at org.zkoss.zul.Label.invalidate(Label.java:324)
at org.zkoss.zul.Label.setValue(Label.java:64)
at com.ibs.SMSClient$1.messageReceived(SMSClient.java:106)
at dk.daimi.jones.impl.sms.SMSImpl.notifyNMIListeners(SMSImpl.java:146)
at dk.daimi.jones.impl.sms.CSMSService.received(CSMSService.java:33)
at org.jsmsengine.CService$CReceiveThread.run(CService.java:1665)
java code
NMIListener myNMIListener = new NMIListener() { public void messageReceived(SMSMessage smsMessage) { // System.out.println("Received SMS from '" + smsMessage.getAddress() + "'"); // System.out.println("Text: '" + smsMessage.getData() + "'"); Label lblSender = (Label)getComponent("sender"); Label lblMessage = (Label)getComponent("msg"); lblSender.setValue(smsMessage.getAddress()); lblMessage.setValue(smsMessage.getData()); } };
TIA,
Andy Susanto
Hi,
Did you use the server push?
If so, please invoke Executions.activate(desktop) before you manipulate.
/Jumper
Hey Jumper,
I have the same error. I created my own system for moving events around the place though. In the beginning I pass a reference to my page (a GenericForwardComposer subclass) to an event manager. I then later try to update the date, but it doesn't work. I get that Components can be accessed only in event listeners.
If I enable desktop.enableServerPush before Executions.activate(desktop), the browser seems to get stuck and not display my page.
public class Datebox extends GenericForwardComposer implements Composer, ActionListener { org.zkoss.zul.Datebox autoDbxDate; // Date boxes to be updated org.zkoss.zul.Datebox manualDbxDate; // Date boxes to be updated public Datebox() { ApplicationContext context = ApplicationContext.getInstance(); // Fetch Singleton EventDispatcher dispatcher = context.getEventDispatcher(); // Fetch my custom event dispatcher dispatcher.addEventListener(this, DateEvent.class); // Add this (Implements my custom ActionListener) } @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); desktop.enableServerPush(true); // Enable Push Executions.activate(desktop); // Enable Push } public void onChange$autoDbxDate() { try { Messagebox.show("Datebox Clicked:" + date.toString()); } catch (InterruptedException ex) { System.out.println("InterruptedException"); } } public void updateDate(Date date) { try { Messagebox.show("Datebox Clicked:" + date.toString()); } catch (InterruptedException ex) { System.out.println("InterruptedException"); } } @Override public void actionPerformed(Event e) { // This is my actionPerformed method required by my interface if (e instanceof DateEvent) { DateEvent dateEvent = (DateEvent) e; Date date = dateEvent.getDate(); autoDbxDate.setValue(date); manualDbxDate.setValue(date); } } }
Any ideas much appreciated...
Alternatively, instead of using my own custom event listener framework, perhaps I should implement some kind of ZK event system?
ANSWERED:
I answered my own question.
In the beginning:
public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); desktop.enableServerPush(true); }
Later:
Executions.activate(desktop); // update components Executions.deactivate(desktop);
I now have a problem that I set event listeners in the pages (which works fine) to update the components, but as soon a user closes or refreshes that page, then trying to fire the actionPerformed method in the page crashes. Any ideas appreciated...
UPDATE: Looks like the thing crashes then trying to access pages that have been closed or refreshed. Most likely now that I'm keeping a reference to the page, the page is not being destroyed. How do I check to see if the page is still active?
You can check the desktop belonging to the page whether is alive or not.
Thanks Jumper.
For some odd reason, desktop.isAlive() is still returning true even though I have closed the GenericForwardComposer client browser window.
Do you have any ideas why? Is there another way I can check whether a page is alive, destroy it manually when it is closed, or run a thread that checks for open Windows and updates a list?
public class Datebox extends GenericForwardComposer implements Composer, ActionListener { org.zkoss.zul.Datebox manualDbxDate; org.zkoss.zul.Timebox manualTbxTime; @Override public void doAfterCompose(Component comp) throws Exception { System.out.println("Creating Page"); super.doAfterCompose(comp); System.out.println("Enabling Page Server Push"); if (!desktop.isServerPushEnabled()) { desktop.enableServerPush(true); } System.out.println("Adding Event Listener"); ApplicationContext context = ApplicationContext.getInstance(); EventDispatcher dispatcher = context.getEventDispatcher(); dispatcher.addEventListener(this, DateEvent.class); } @Override public void actionPerformed(Event e) { if (e instanceof DateEvent && desktop != null && desktop.isAlive()) { try { Executions.activate(desktop); DateEvent dateEvent = (DateEvent) e; Date date = dateEvent.getDate(); manualDbxDate.setValue(date); manualTbxTime.setValue(date); Executions.deactivate(desktop); } catch (InterruptedException ex) { System.out.println("Interrupted"); } catch (DesktopUnavailableException ex) { System.out.println("Desktop Unavailable"); } } else { System.out.println("This page is dead or not a Date Event"); } } @Override public void finalize() throws Throwable { super.finalize(); System.out.println("FINALIZING - - - - -"); ApplicationContext context = ApplicationContext.getInstance(); EventDispatcher dispatcher = context.getEventDispatcher(); dispatcher.removeEventListener(this); } }
Is creating an external singleton event listener the "best" way to do this. I'm just really wanting to create a simple system where an event on the server, and update the display of users currently on that page. Perhaps I'm getting too complicated. Any ideas appreciated.
Also, I'm told that ZK by default uses server polling. How do I change it to use comet?
Some browser won't fire an event to tell the server that the browser is closed, so in that case you have to wait a timeout of the desktop(by default 30 minutes), and the comet server push is applicable to ZK EE version.
Any ideas though, show I can stop the Threads from crashing. In the code above, if I call actionPerformed(Event e) {} - but if the page is no longer active, the Thread hangs. This is actually why I created the Thread in the first place, so that at least just the Thread hangs, but execution continues.
Advice appreciated.
Asked: 2009-04-02 12:53:37 +0800
Seen: 1,785 times
Last updated: Feb 13 '17