How to gracefully interrupt running script when using SwingWorker and JFrame? --- not possible with the thread model
*************** a revised version of the provided sample code by RaiMan *************
*** comments:
- with such a solution it is not possible to kill the running SwingWorker thread (the python interpreter simply ignores the bgThread.
- to use a stop button, to end a script only works, if the script does not make continuous use of the mouse (you will not get a chance to click the button). a good alternative is a stop hotkey (see revised sample)
- to add a global kill option for the SwingWorker thread, you either have to run the script via subprocess module or implement something like that hack:
https:/
- another option is to make the script aware of a stop request (as done in the revised sample below)
- the triggered script should not run into an infinite loop or wait, since this can only be stopped by aborting the wrapping script or even the IDE
- the script should be tested before adding it into such a wrapper, because most errors simply do not produce any helpful output (an option is to make the script run standalone and then use runScript() in the wrapper)
- print statements should only have one parameter, otherwise printouts from the different threads get mangled (use the Python string formatting ""%() to assure that - see sample)
- the start button should only be activated again by code, that is triggered by the thread on termination (in the revised example I use the done() callback for that (otherwise it might be possible to trigger a new run, while one is still running)
from javax.swing import JButton, JFrame, JTextField, JPanel
from java.lang import Runnable, InterruptedExce
from java.util.
from javax.swing import SwingWorker, SwingUtilities
from java.lang import *
from java.awt.event import ActionListener, WindowAdapter
import threading
class BgTask(
def __init__(self, gui):
self.gui = gui
def shouldStop(self, event=None):
self.stopRun = True
def someInit(self):
print "**** started"
Env.
# @Override
def doInBackground(
self.
for i in range(10):
if self.stopRun: break
# for 1.1.x before 2016-05-21
wait(1)
def showState(self, msg):
if self.stopRun:
print "%s - shouldStop reveived" % (msg)
else:
print "%s - %s" % (msg, self.getState())
# @Override
def done(self):
self.
print "**** ended"
class Example:
def __init__(self):
frame = JFrame("Automated Testing")
def startRun(
self.bgTask = BgTask(self)
def stopRun(self, event):
def _setButtonState
def hasEnded(self):
class Adapter(
# @Override
def windowClosing(self, event):
class Runnable(Runnable):
def __init__(self, runFunction):
def run(self):
SwingUtilities.
endCondition = threading.
endCondition.
endCondition.wait()
endCondition.
-------
Thanks to the help provided here I've created a JFrame to allow me more advanced user interaction and a custom control GUI. I only have one issue at this point, once the items runing in doInBackground (BgTask SwingWorker), you can not gracefully stop stop the script. I get the following error: java.lang.
I tried to add a try/except to catch the exception, but it doesn't seem to work. Also when I try to use the CTRL+ALT+c hot key it stops the program and makes my JFrame and also the IDE unresponsive.
I'm using Windows 7 64bit, I'm using SikulixIDE 1.1.0
CODE:
from javax.swing import JButton, JFrame, JTextField, JPanel
from java.lang import Runnable, InterruptedExce
from java.util.
from javax.swing import SwingWorker, SwingUtilities
from java.lang import *
from java.awt.event import ActionListener, WindowAdapter
import threading
class BgTask(
def __init__(self, gui):
self.gui = gui
def doInBackground(
try:
wait(5)
except InterruptedExce
print "***Automation Stuff Should End***"
def done(self):
try:
except ExecutionException, e:
raise SystemExit, e.getCause()
# print e.getCause()
class Example:
def _setButtonState
def stopSomething(self, event):
def doSomething(
self.bgTask = BgTask(self)
def __init__(self):
frame = JFrame("Gamma Automated Testing")
endCondition = threading.
class Adapter(
def windowClosing(self, event):
class Runnable(Runnable):
def __init__(self, runFunction):
def run(self):
if __name__ == '__main__':
SwingUtilit
endConditio
# Example()
endConditio
endConditio
Question information
- Language:
- English Edit question
- Status:
- Answered
- For:
- SikuliX Edit question
- Assignee:
- No assignee Edit question
- Last query:
- Last reply:
Can you help with this problem?
Provide an answer of your own, or ask Mike for more information if necessary.