Hi Andrei,
Yes, I remember the discussion about this earlier. There was a
good reason for being able to override the default checker, as in your case
running inside another container. It’s just that overriding the checker, for
instance, to just silence the assertion, is not a particularly good idea,
except, perhaps, for the very narrow case where you have to get something
working ASAP, and are now alerted to the fact that you will soon have to fix
the background thread code, AND put back the assert once you’re done.
From: Andrei Pozolotin [mailto:[email protected]]
Sent: Monday, January 16, 2012 12:41 PM
To: Roger L. Whitcomb
Cc: [email protected]; [email protected]
Subject: Re: 2.0.1 release and threads
Roger:
yes, good point;
and in my case I have legitimate scenario
when I have to provide alternative checker, since I am running inside osgi
launcher,
which is not covered by the default pivot checker implementation;
Andrei.
-------- Original Message --------
Subject: Re: 2.0.1 release and threads
From: Roger L. Whitcomb <[email protected]>
<mailto:[email protected]>
To: Andrei Pozolotin <[email protected]>
<mailto:[email protected]> , [email protected]
Cc: [email protected]
Date: Mon 16 Jan 2012 02:34:03 PM CST
But note that while this would eliminate the exception thrown by this “assert”
it will not eliminate the subtle bugs that are really there because your UI
updates are not being done in the event thread. So, even though things appear
to work, there really are problems that will end up biting you at some point.
That was the reason for putting in this assert, to alert you to the fact that
there are really problems that you are not aware of.
~Roger
From: Andrei Pozolotin [mailto:[email protected]]
Sent: Monday, January 16, 2012 12:31 PM
To: [email protected]
Cc: Roger L. Whitcomb; [email protected]
Subject: Re: 2.0.1 release and threads
Lukas:
you can provide a temporary work around
by providing an alternative implementation to thread checker used by assert
org.apache.pivot.wtk.Container.assertEventDispatchThread
Andrei
-------- Original Message --------
Subject: Re: 2.0.1 release and threads
From: Roger L. Whitcomb <[email protected]>
<mailto:[email protected]>
To: [email protected], [email protected]
Date: Mon 16 Jan 2012 12:39:29 PM CST
Hi Lukas,
That approach is still valid (and encouraged) EXCEPT that all updates
to the UI MUST happen in the Event Dispatch Thread (or 'EDT'). This is now
enforced in 2.0.1 (as you can see). This is inherent, not only in Pivot, but
all other GUI frameworks (that I know of). So, even though it "appeared" to
work fine with 2.0, there are/were subtle problems that you just didn't see yet.
What you need to do is use either a TaskAdapter class or call the
ApplicationContext.queueCallback() method to schedule your UI updates in the
EDT, rather than doing them directly in the background thread. For an example
you can look at the Tutorial here:
http://pivot.apache.org/tutorials/background-tasks.html. I can step you
through your code in more detail if you need more help. Our application also
has a number of places where we have needed to do this.
I'm going to transfer this to the User list since this is not a
developer issue, per se, since it is not a bug. It is, however, something that
has definitely changed (for the better) in 2.0.1.
Thank you for using Pivot, though!!
~Roger
-----Original Message-----
From: Lukáš Macháček [mailto:[email protected]]
Sent: Monday, January 16, 2012 8:17 AM
To: [email protected]
Subject: 2.0.1 release and threads
Hi all,
I am now testing coming 2.0.1 release of Pivot libraries with my desktop
application developed during previous year on Pivot 2.0 and am facing
one great problem with threads :-(
Every task which loads data at background and worked in 2.0 well now
throws exception like this:
java.lang.IllegalStateException: this method can only be called from the
AWT event dispatch thread, and not from "Thread-26"
at org.apache.pivot.wtk.Container$1.check(Container.java:872)
at
org.apache.pivot.wtk.Container.assertEventDispatchThread(Container.java:880)
at org.apache.pivot.wtk.Component.repaint(Component.java:2047)
at org.apache.pivot.wtk.Component.repaint(Component.java:1998)
at
org.apache.pivot.wtk.skin.ComponentSkin.repaintComponent(ComponentSkin.java:351)
at
org.apache.pivot.wtk.skin.ComponentSkin.repaintComponent(ComponentSkin.java:346)
at
org.apache.pivot.wtk.skin.terra.TerraTableViewSkin.enabledChanged(TerraTableViewSkin.java:1394)
at
org.apache.pivot.wtk.Component$ComponentStateListenerList.enabledChanged(Component.java:399)
at org.apache.pivot.wtk.Component.setEnabled(Component.java:2173)
at cz.cgrim.alchemist.dql.RunQueryTask.execute(RunQueryTask.java:58)
at cz.cgrim.alchemist.dql.RunQueryTask.execute(RunQueryTask.java:23)
at
org.apache.pivot.util.concurrent.Task$ExecuteCallback.run(Task.java:42)
at
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
at java.util.concurrent.FutureTask.run(FutureTask.java:166)
at java.lang.Thread.run(Thread.java:722)
In this example at first it disables TableView (to disable user
interaction during background load of data), than it loaded results from
DQL query into that TableView and at the end it enabled that TableView.
I have tens of use cases with similar approach in my application used to
load data at background because it can take long time to finish while
user can work on another tasks.
Another equal problem with thread has occurred for example in my custom
Log4J Appender:
Exception in thread "Timer-2" java.lang.IllegalStateException: this
method can only be called from the AWT event dispatch thread, and not
from "Timer-2"
at org.apache.pivot.wtk.Container$1.check(Container.java:872)
at
org.apache.pivot.wtk.Container.assertEventDispatchThread(Container.java:880)
at org.apache.pivot.wtk.Component.invalidate(Component.java:1955)
at
org.apache.pivot.wtk.skin.ComponentSkin.invalidateComponent(ComponentSkin.java:340)
at
org.apache.pivot.wtk.skin.TextAreaSkinParagraphView.textRemoved(TextAreaSkinParagraphView.java:419)
at
org.apache.pivot.wtk.TextArea$Paragraph$ParagraphListenerList.textRemoved(TextArea.java:55)
at
org.apache.pivot.wtk.TextArea$Paragraph.removeText(TextArea.java:153)
at org.apache.pivot.wtk.TextArea.insertText(TextArea.java:757)
at org.apache.pivot.wtk.TextArea.insertText(TextArea.java:730)
at
cz.cgrim.alchemist.logger.TextAreaAppender.append(TextAreaAppender.java:41)
at
org.apache.log4j.AppenderSkeleton.doAppend(AppenderSkeleton.java:251)
at
org.apache.log4j.helpers.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:66)
at org.apache.log4j.Category.callAppenders(Category.java:206)
at org.apache.log4j.Category.forcedLog(Category.java:391)
at org.apache.log4j.Category.log(Category.java:856)
at com.documentum.fc.common.DfLogger.warn(DfLogger.java:151)
at
com.documentum.fc.client.impl.bof.cache.ClassCacheManager$CacheCleanupTask.run(ClassCacheManager.java:602)
at java.util.TimerThread.mainLoop(Timer.java:555)
at java.util.TimerThread.run(Timer.java:505)
Here I simply implement AppenderSkeleton and append every line from
LoggingEvent into Pivot's TextPane. Log4J runs it in separate thread.
Please, is now there another approach how to use threads and Pivot's
Task to do changes in GUI or is it a bug? In 2.0 release everything
spoken here worked like a charm.
Thanks for an advance.
Lukas Machacek