Changeset 2407


Ignore:
Timestamp:
Feb 28, 2010 7:39:48 AM (9 years ago)
Author:
wehart
Message:

Revisions to get the GUI working with
subprocess execution.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • coopr.gui.pyomo/trunk/coopr/gui/pyomo/GUI.py

    r2397 r2407  
     1
     2import time
     3import sys
    14from pawt import swing
    25from java.awt import GridBagLayout, GridBagConstraints, FlowLayout
     
    912import coopr.pyomo.scripting
    1013from threading import Thread
     14import pyutilib.misc
     15import pyutilib.subprocess
     16import StringIO
     17from javax.swing import SwingWorker, SwingUtilities
     18from java.util.concurrent import CancellationException
     19from java.util.concurrent import ExecutionException
     20from java.lang import Runtime, Runnable, ProcessBuilder
     21from java.io import InputStreamReader, BufferedReader
     22from java.awt import Font
     23
    1124
    1225
     
    8194
    8295
    83 class RunPyomo(Thread):
    84 
    85     def __init__(self, options, args, parser):
    86         self.options=options
    87         self.args=args
    88         self.parser=parser
    89 
    90     def run(self):
    91         self.ostream = StringIO.StringIO()
    92         pyutilib.misc.redirect(self.ostream)
    93         coopr.pyomo.scripting.pyomo.run_pyomo(options, args, parser)
    94         pyutilib.misc.reset_redirect()
     96class PyomoWorker(SwingWorker):
     97    "Class implementing long running task as a SwingWorker thread"
     98
     99    def __init__(self, options, args, parser, gui, shell=True):
     100        SwingWorker.__init__(self)
     101        self.options=options
     102        self.args=args
     103        self.parser=parser
     104        self.shell=shell
     105        self.gui=gui
     106        self.cmd=[]
     107        self.stdout_reader_done = False
     108        self.stderr_reader_done = False
     109
     110    def doInBackground(self):
     111        pyomocmd = os.path.dirname(sys.executable)+os.sep+"pyomo"
     112        self.cmd = [sys.executable, pyomocmd]
     113        for opt in self.parser.option_list:
     114            if len(opt._long_opts) > 0:
     115                key = opt._long_opts[0][2:]
     116            else:
     117                key = opt._short_opts[0][1:]
     118            if self.options[key] is None:
     119                continue
     120            if self.options[key] == opt.default:
     121                continue
     122            if type(self.options[key]) is list:
     123                for item in self.options[key]:
     124                    self.cmd.append("--"+key)
     125                    self.cmd.append(str(item))
     126            else:
     127                self.cmd.append("--"+key)
     128                self.cmd.append(str(self.options[key]))
     129        for arg in self.args[1:]:
     130            if arg != '':
     131                self.cmd.append(arg)
     132        self.update("Executing the following command:\n\n  "+' '.join(self.cmd)+"\n", self.gui)
     133
     134        def stdout_reader(stream, self):
     135            s = ''
     136            while (s != None):
     137                if self.isCancelled():
     138                    self.stdout_reader_done=True
     139                    return
     140                s = stream.readLine()
     141                if s is None:
     142                    self.stdout_reader_done=True
     143                    return
     144                else:
     145                    self.update(s+"\n", self.gui)
     146            self.stdout_reader_done=True
     147
     148        def stderr_reader(stream, buffer, self):
     149            s = ''
     150            while (s != None):
     151                if self.isCancelled():
     152                    self.stderr_reader_done=True
     153                    return
     154                s = stream.readLine()
     155                if s is None:
     156                    self.stderr_reader_done=True
     157                    return
     158                else:
     159                    buffer += s
     160            self.stderr_reader_done=True
     161
     162        self.cmd = ['cmd.exe', '/C', 'call'] + self.cmd
     163
     164        builder = ProcessBuilder(self.cmd)
     165        proc = builder.start()
     166        stdInput = BufferedReader(InputStreamReader(proc.getInputStream()))
     167        stdError = BufferedReader(InputStreamReader(proc.getErrorStream()))
     168        #
     169        try:
     170            self.update("\n--- PYOMO START STDOUT ---\n\n", self.gui)
     171            self.buffer=''
     172            self.outt = Thread(target=stdout_reader, args=(stdInput,self))
     173            self.outt.daemon = True
     174            self.outt.start()
     175            self.errt = Thread(target=stderr_reader, args=(stdError,self.buffer,self))
     176            self.errt.daemon = True
     177            self.errt.start()
     178            ##print "HERE 2"
     179            self.outt.join()
     180            ##print "HERE 3"
     181            self.errt.join()
     182            ##print "HERE 4"
     183            self.outt = None
     184            self.errt = None
     185        except Exception, e:
     186            raise e
     187            ##print "HERE 5",str(e)
     188        finally:
     189            ##print "HERE 6"
     190            self.final_output()
     191            self.finish(self.gui)
     192   
     193    def final_output(self):
     194        #while not self.stdout_reader_done or not self.stderr_reader_done:
     195            #print "HERE Y"
     196            #time.sleep(0.1)
     197        print "HERE X"
     198        if self.isCancelled():
     199            self.update("--- Pyomo Solver Terminated Early!  ----\n", self.gui)
     200        self.update("\n--- PYOMO END STDOUT ---\n", self.gui)
     201        #
     202        if len(self.buffer) > 0:
     203            self.update("\n\n--- PYOMO START STDERR ---\n\n", self.gui)
     204            self.update(self.buffer, self.gui)
     205            self.update("\n--- PYOMO END STDERR ---\n", self.gui)
     206
     207    def finish(self, gui):
     208        class updater( java.lang.Runnable ) :
     209            def run( self ) :
     210                gui._setButtonStates(started=False, finished=True)
     211        if SwingUtilities.isEventDispatchThread() :
     212            updater().run()
     213        else :
     214            SwingUtilities.invokeLater( updater() )
     215
     216    def update(self, text, gui):
     217        #print "X",text
     218        tab = gui.tab_info[gui.tabbed.getSelectedIndex()]
     219        # now update the GUI,  create an java.lang.Runnable that
     220        # does the work
     221        class updater( java.lang.Runnable ) :
     222            def run( self ) :
     223                tab.output.append(text)
     224        #
     225        if SwingUtilities.isEventDispatchThread() :
     226            # we are already in the AWT_EventQueue thread, it is
     227            # safe to touch the GUI
     228            updater().run()
     229        else :
     230            # request that the updater be run in the
     231            # AWT_EventQueue thread
     232            SwingUtilities.invokeLater( updater() )
     233        ###print "UPDATE - done"
     234
     235    def process(self, text):
     236        self.gui.output.append(text)
     237
     238    def done(self):
     239        try:
     240            self.get()
     241        except CancellationException, e:
     242            # ignore exception caused when worker is explicitly canceled
     243            pass
     244        except ExecutionException, e:
     245            raise SystemExit, e.getCause()
     246
    95247
    96248
     
    119271        # Finish up and set the size
    120272        self.frame.pack()
    121         self.frame.visible = 1
     273        # ACTIVATE AND THEN SET VISIBLE
     274        self.frame.setVisible(1)
    122275        self.frame.size = self.frame.getPreferredSize()
    123276
     
    151304        bag.addRow(tab.text2)
    152305        #
    153         # Creating a text area for the command that will be executed
    154         #
    155         ##tab.input = swing.JTextArea("", 6, 80)
    156         ##bag.addRow(tab.input)
    157         ##tab.input.append("COMMAND %d" % self.tab_id)
    158 
    159         #
    160306        # create panel for the options in the command line
    161307        #
    162308        options_panel = swing.JPanel(FlowLayout(alignment=FlowLayout.LEFT))
    163         tab.parser = coopr.pyomo.scripting.pyomo.create_parser()
    164         tab.parse_options = tab.parser.parse_args(args=['pyomo'])[0]
     309        tab.parser = coopr.pyomo.scripting.pyomo.create_parser()
     310        tab.parse_options = tab.parser.parse_args(args=['pyomo'])[0]
    165311        tab.options_pane, tab.options_table = self.create_options_table(tab.parser, tab.parse_options)
    166312        options_panel.add(tab.options_pane)
     
    172318        tab.buttonExecute = swing.JButton("Execute", actionPerformed=self._buttonExecute)
    173319        buttons.add(tab.buttonExecute)
     320        tab.buttonStop = swing.JButton("Stop", actionPerformed=self._buttonStop)
     321        buttons.add(tab.buttonStop)
    174322        tab.buttonClearOutput = swing.JButton("Clear Output", actionPerformed=self._buttonClearOutput)
    175323        buttons.add(tab.buttonClearOutput)
    176324        bag.addRow(buttons)
    177         #
    178         tab.output = swing.JTextArea("",6,80)
     325        self._setButtonStates(started=False, finished=True)
     326        #
     327        tab.output = swing.JTextArea("",15,80)
     328        tab.output.setFont( Font('Courier New', Font.PLAIN, 12) )
     329        #tab.output.setFont( Font('Lucida Console', Font.PLAIN, 12) )
    179330        pane = swing.JScrollPane(tab.output,\
    180                     verticalScrollBarPolicy=swing.JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
    181                     size=(1000,10000))
     331                    verticalScrollBarPolicy=swing.JScrollPane.VERTICAL_SCROLLBAR_ALWAYS)
     332                    #size=(1000,10000))
    182333        bag.addRow(pane, weighty=1.0)
    183         tab.output.append("DRAFT GUI for PYOMO COMMAND DRIVER\n\n")
     334        #tab.output.append("DRAFT GUI for PYOMO COMMAND DRIVER\n\n")
    184335
    185336    def create_options_table(self, parser, parse_options):
     
    187338        options_table.initialize(parser, parse_options)
    188339        scrollPane = swing.JScrollPane()
    189         scrollPane.setPreferredSize(java.awt.Dimension(600,200))
     340        scrollPane.setPreferredSize(java.awt.Dimension(600,100))
     341        scrollPane.setMinimumSize(java.awt.Dimension(300,100))
    190342        scrollPane.getViewport().setView(options_table)
    191343        return scrollPane, options_table
     
    223375        return menubar
    224376
     377    def _setButtonStates(self, started, finished):
     378        tab = self.tab_info[self.tabbed.getSelectedIndex()]
     379        tab.buttonExecute.enabled = not started
     380        tab.buttonStop.enabled = started
     381        tab.buttonClearOutput.enabled = finished
     382
    225383    def _fileNewCommand(self, event=None):
    226384        self.create_tab()
     
    279437
    280438    def _buttonExecute(self, event=None):
    281         if not self.tab_info[self.tabbed.getSelectedIndex()].thread is None:
    282             return
    283         tab = self.tab_info[self.tabbed.getSelectedIndex()]
    284         options = tab.options_table.get_options()
    285         #
    286         thread = RunPyomo(options, ['pyomo', tab.text1.text, tab.text2.text], tab.parser)
    287         tab.thread = thread
    288         thread.start()
     439        self._setButtonStates(started=True, finished=False)
     440        tab = self.tab_info[self.tabbed.getSelectedIndex()]
     441        tab.output.text = ""
     442        options = tab.options_table.get_options()
     443        tab.PyomoWorker = PyomoWorker(options, ['pyomo', tab.text1.text, tab.text2.text], tab.parser, self)
     444        tab.PyomoWorker.execute()
     445
     446    def _buttonStop(self, event=None):
     447        #self._setButtonStates(started=False, finished=True)
     448        tab = self.tab_info[self.tabbed.getSelectedIndex()]
     449        tab.PyomoWorker.cancel(True)
     450        #tab.PyomoWorker = None
    289451
    290452    def _buttonClearOutput(self, event=None):
Note: See TracChangeset for help on using the changeset viewer.