Skip to content

Commit 7aabe89

Browse files
committed
added simple events
1 parent bf76870 commit 7aabe89

File tree

3 files changed

+212
-3
lines changed

3 files changed

+212
-3
lines changed

src/main/java/com/github/fracpete/jshell/JShellPanel.java

Lines changed: 93 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020

2121
package 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;
2326
import com.github.fracpete.processoutput4j.core.StreamingProcessOutputType;
2427
import com.github.fracpete.processoutput4j.core.StreamingProcessOwner;
2528
import com.github.fracpete.processoutput4j.output.StreamingProcessOutput;
@@ -50,7 +53,9 @@
5053
import java.io.File;
5154
import java.nio.file.Files;
5255
import java.util.ArrayList;
56+
import java.util.HashSet;
5357
import 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!\nCannot 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());
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* This program is free software: you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License as published by
4+
* the Free Software Foundation, either version 3 of the License, or
5+
* (at your option) any later version.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
16+
/*
17+
* JShellEvent.java
18+
* Copyright (C) 2018 University of Waikato, Hamilton, NZ
19+
*/
20+
21+
package com.github.fracpete.jshell.event;
22+
23+
import com.github.fracpete.jshell.JShellPanel;
24+
25+
import java.util.EventObject;
26+
27+
/**
28+
* Events sent by the {@link JShellPanel}.
29+
*
30+
* @author FracPete (fracpete at waikato dot ac dot nz)
31+
*/
32+
public class JShellEvent
33+
extends EventObject {
34+
35+
/** the type of event. */
36+
public enum EventType {
37+
SCRIPT_LOAD_SUCCESS,
38+
SCRIPT_LOAD_FAILURE,
39+
SCRIPT_SAVE_SUCCESS,
40+
SCRIPT_SAVE_FAILURE,
41+
SCRIPT_RUN_SETUP_FAILURE,
42+
SCRIPT_RUN,
43+
SCRIPT_RUN_FAILURE,
44+
SCRIPT_RUN_SUCCESS,
45+
SCRIPT_STOP,
46+
SCRIPT_FINISHED,
47+
OUTPUT_CLEARED,
48+
OUTPUT_SAVE_SUCESS,
49+
OUTPUT_SAVE_FAILURE,
50+
}
51+
52+
/** the event type. */
53+
protected EventType m_Type;
54+
55+
/**
56+
* Constructs a prototypical Event.
57+
*
58+
* @param source the panel on which the Event initially occurred
59+
* @throws IllegalArgumentException if source is null
60+
*/
61+
public JShellEvent(JShellPanel source, EventType type) {
62+
super(source);
63+
m_Type = type;
64+
}
65+
66+
/**
67+
* Returns the panel that triggered the event.
68+
*
69+
* @return the source panel
70+
*/
71+
public JShellPanel getPanel() {
72+
return (JShellPanel) getSource();
73+
}
74+
75+
/**
76+
* Returns the event type.
77+
*
78+
* @return the event type
79+
*/
80+
public EventType getType() {
81+
return m_Type;
82+
}
83+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* This program is free software: you can redistribute it and/or modify
3+
* it under the terms of the GNU General Public License as published by
4+
* the Free Software Foundation, either version 3 of the License, or
5+
* (at your option) any later version.
6+
*
7+
* This program is distributed in the hope that it will be useful,
8+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
* GNU General Public License for more details.
11+
*
12+
* You should have received a copy of the GNU General Public License
13+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
14+
*/
15+
16+
/*
17+
* JShellListener.java
18+
* Copyright (C) 2018 University of Waikato, Hamilton, NZ
19+
*/
20+
21+
package com.github.fracpete.jshell.event;
22+
23+
/**
24+
* Interface for classes that listen to events of the JShellPanel.
25+
*
26+
* @author FracPete (fracpete at waikato dot ac dot nz)
27+
*/
28+
public interface JShellListener {
29+
30+
/**
31+
* Gets triggered with any event in the JShellPanel.
32+
*
33+
* @param e the event
34+
*/
35+
public void jshellEventOccurred(JShellEvent e);
36+
}

0 commit comments

Comments
 (0)