2020
2121package com .github .fracpete .jshell ;
2222
23+ import com .github .fracpete .jshell .event .JShellEvent ;
24+ import com .github .fracpete .jshell .event .JShellEvent .EventType ;
25+ import com .github .fracpete .jshell .event .JShellListener ;
2326import com .github .fracpete .processoutput4j .core .StreamingProcessOutputType ;
2427import com .github .fracpete .processoutput4j .core .StreamingProcessOwner ;
2528import com .github .fracpete .processoutput4j .output .StreamingProcessOutput ;
5053import java .io .File ;
5154import java .nio .file .Files ;
5255import java .util .ArrayList ;
56+ import java .util .HashSet ;
5357import java .util .List ;
58+ import java .util .Set ;
5459
5560/**
5661 * Panel for performing scripting via jshell. Requires Java 9.
@@ -102,6 +107,9 @@ public class JShellPanel
102107 /** executes the script. */
103108 protected transient StreamingProcessOutput m_Execution ;
104109
110+ /** the listeners that listen for changes. */
111+ protected Set <JShellListener > m_JShellListeners ;
112+
105113 /**
106114 * Initializes the members.
107115 */
@@ -113,6 +121,8 @@ protected void initialize() {
113121 m_FileChooserOutput = new BaseFileChooser ();
114122 m_FileChooserOutput .addChoosableFileFilter (new ExtensionFileFilter ("Text file" , "txt" ));
115123 m_FileChooserOutput .setAcceptAllFileFilterUsed (true );
124+
125+ m_JShellListeners = new HashSet <>();
116126 }
117127
118128 /**
@@ -207,13 +217,22 @@ protected void finishInit() {
207217 updateButtons ();
208218 }
209219
220+ /**
221+ * Returns whether a script is currently running.
222+ *
223+ * @return true if a script is running
224+ */
225+ public boolean isRunning () {
226+ return (m_Execution != null );
227+ }
228+
210229 /**
211230 * Updates the state of the buttons.
212231 */
213232 protected void updateButtons () {
214233 boolean running ;
215234
216- running = ( m_Execution != null );
235+ running = isRunning ( );
217236
218237 // script
219238 m_ButtonScriptLoad .setEnabled (!running );
@@ -250,9 +269,11 @@ public void loadScript(File script) {
250269 try {
251270 lines = Files .readAllLines (script .toPath ());
252271 m_TextCode .setText (Utils .flatten (lines , "\n " ));
272+ notifyJShellListeners (new JShellEvent (this , EventType .SCRIPT_LOAD_SUCCESS ));
253273 }
254274 catch (Exception e ) {
255275 GUIHelper .showErrorMessage (this , "Failed to load script from: " + script , e );
276+ notifyJShellListeners (new JShellEvent (this , EventType .SCRIPT_LOAD_FAILURE ));
256277 }
257278
258279 updateButtons ();
@@ -272,8 +293,13 @@ public void saveScript() {
272293
273294 script = m_FileChooserScript .getSelectedFile ();
274295 msg = FileUtils .writeToFileMsg (script .getAbsolutePath (), m_TextCode .getText (), false , null );
275- if (msg != null )
296+ if (msg != null ) {
276297 GUIHelper .showErrorMessage (this , "Failed to save script to : " + script + "\n " + msg );
298+ notifyJShellListeners (new JShellEvent (this , EventType .SCRIPT_SAVE_FAILURE ));
299+ }
300+ else {
301+ notifyJShellListeners (new JShellEvent (this , EventType .SCRIPT_SAVE_SUCCESS ));
302+ }
277303
278304 updateButtons ();
279305 }
@@ -289,6 +315,7 @@ public void runScript() {
289315 ProcessBuilder builder ;
290316 Runnable run ;
291317
318+ stopScript ();
292319 clearScriptOutput ();
293320
294321 // create tmp file name
@@ -297,6 +324,7 @@ public void runScript() {
297324 }
298325 catch (Exception e ) {
299326 GUIHelper .showErrorMessage (this , "Failed to create temporary file for script!\n Cannot execute script!" , e );
327+ notifyJShellListeners (new JShellEvent (this , EventType .SCRIPT_RUN_SETUP_FAILURE ));
300328 return ;
301329 }
302330
@@ -310,6 +338,7 @@ public void runScript() {
310338 if (msg != null ) {
311339 tmpFile .delete ();
312340 GUIHelper .showErrorMessage (this , "Failed to write script to temporary file: " + tmpFile + "\n " + msg );
341+ notifyJShellListeners (new JShellEvent (this , EventType .SCRIPT_RUN_SETUP_FAILURE ));
313342 return ;
314343 }
315344
@@ -329,16 +358,23 @@ public void runScript() {
329358 public void run () {
330359 try {
331360 m_Execution .monitor (builder );
361+ if (m_Execution .getExitCode () != 0 )
362+ notifyJShellListeners (new JShellEvent (JShellPanel .this , EventType .SCRIPT_RUN_FAILURE ));
363+ else
364+ notifyJShellListeners (new JShellEvent (JShellPanel .this , EventType .SCRIPT_RUN_SUCCESS ));
332365 }
333366 catch (Exception e ) {
334367 GUIHelper .showErrorMessage (JShellPanel .this , "Failed to execute script!" , e );
368+ notifyJShellListeners (new JShellEvent (JShellPanel .this , EventType .SCRIPT_RUN_FAILURE ));
335369 }
370+ notifyJShellListeners (new JShellEvent (JShellPanel .this , EventType .SCRIPT_FINISHED ));
336371 m_Execution = null ;
337372 tmpFile .delete ();
338373 updateButtons ();
339374 }
340375 };
341376 new Thread (run ).start ();
377+ notifyJShellListeners (new JShellEvent (this , EventType .SCRIPT_RUN ));
342378
343379 updateButtons ();
344380 }
@@ -350,6 +386,7 @@ public void stopScript() {
350386 if (m_Execution != null ) {
351387 m_Execution .destroy ();
352388 m_Execution = null ;
389+ notifyJShellListeners (new JShellEvent (this , EventType .SCRIPT_STOP ));
353390 }
354391
355392 updateButtons ();
@@ -360,6 +397,7 @@ public void stopScript() {
360397 */
361398 public void clearScriptOutput () {
362399 m_TextOutput .setText ("" );
400+ notifyJShellListeners (new JShellEvent (this , EventType .OUTPUT_CLEARED ));
363401 updateButtons ();
364402 }
365403
@@ -375,12 +413,35 @@ public void saveScriptOutput() {
375413 return ;
376414
377415 msg = FileUtils .writeToFileMsg (m_FileChooserOutput .getSelectedFile ().getAbsolutePath (), m_TextOutput .getText (), false , null );
378- if (msg != null )
416+ if (msg != null ) {
379417 GUIHelper .showErrorMessage (this , msg , "Failed saving output" );
418+ notifyJShellListeners (new JShellEvent (this , EventType .OUTPUT_SAVE_FAILURE ));
419+ }
420+ else {
421+ notifyJShellListeners (new JShellEvent (this , EventType .OUTPUT_SAVE_SUCESS ));
422+ }
380423
381424 updateButtons ();
382425 }
383426
427+ /**
428+ * Returns the current code.
429+ *
430+ * @return the code
431+ */
432+ public String getCode () {
433+ return m_TextCode .getText ();
434+ }
435+
436+ /**
437+ * Returns the current output.
438+ *
439+ * @return the output
440+ */
441+ public String getOutput () {
442+ return m_TextOutput .getText ();
443+ }
444+
384445 /**
385446 * Returns the jshell executable.
386447 *
@@ -436,6 +497,34 @@ public void processOutput(String line, boolean stdout) {
436497 m_TextOutput .setCaretPosition (m_TextOutput .getDocument ().getLength ());
437498 }
438499
500+ /**
501+ * Adds the listener to the internal list.
502+ *
503+ * @param l the listener to add
504+ */
505+ public void addJShellListener (JShellListener l ) {
506+ m_JShellListeners .add (l );
507+ }
508+
509+ /**
510+ * Removes the listener to the internal list.
511+ *
512+ * @param l the listener to remove
513+ */
514+ public void removeJShellListener (JShellListener l ) {
515+ m_JShellListeners .remove (l );
516+ }
517+
518+ /**
519+ * Notifies all the listeners with the specified event.
520+ *
521+ * @param e the event to send
522+ */
523+ protected synchronized void notifyJShellListeners (JShellEvent e ) {
524+ for (JShellListener l : m_JShellListeners )
525+ l .jshellEventOccurred (e );
526+ }
527+
439528 /**
440529 * For testing only.
441530 *
@@ -446,6 +535,7 @@ public static void main(String[] args) {
446535 JShellPanel panel ;
447536
448537 panel = new JShellPanel ();
538+ panel .addJShellListener ((JShellEvent e ) -> System .out .println (e .getType ()));
449539 frame = new BaseFrame ("JShell" );
450540 frame .setIconImage (GUIHelper .getIcon ("jshell.gif" ).getImage ());
451541 frame .getContentPane ().setLayout (new BorderLayout ());
0 commit comments