Process management
The Command Launcher
It is good to have a GUI... but it has to be useful ! And most of the time, it is used to launch a computation program. Several solutions are available:
- Launch a Java thread … but it could not be stopped asynchronously (stop() method is deprecated) except by stopping the GUI!!!
- Launch an executable independent of the GUI
GENIUS makes available classes GJavaCommandLauncher, GCommandLauncher, GExecButton and GExecMenuItem. They will launch:
- Either a Java class, if it owns a « main » static method
- Either an executable (for example issued from a Fortran compilation)
A consequence is that entry data will only be passed by files.
First, we will have to instantiate a GJavaCommandLauncher or a GCommandLauncher. Here is an example launching a Java executable class:
GJavaCommandLauncher cmd;
String path = System.getProperty("java.class.path");
cmd = new GJavaCommandLauncher ( new String[] {"myClass", "args …"}, path,
"Start computation", "Stop computation", null);
// To assign the process output towards the standard output
cmd.setCopyOutputToStdout(true);
Issued from this cmd object, we could get the associated launch button and item menu:
GExecButton butExec = cmd.getGExecButton();
GExecMenuItem itemExec = cmd.getGExecMenuItem();
Pre-process (before)
Considering we implement the GListener interface, we may execute some action inside the before() method (for example, testing that all input data are OK):
public void before(GEvent e) throws GFileManipulatorException {
if ( e.contains(butExec,itemExec) ) { // Launch button or menu have been activated
if ( ! cmd.isRunning() ) { // Program is not yet running, so we may initialize it
if ( valeursOK ) { // Flag indicating values are OK (for example)
GFileManipulation.writeConfig("data.xml", "MAN", objetIhm); // We prepare the input data file
}
else {
cmd.setInhibited(true); // Finally, we do not launch the process !
}
}
}
}
Post-process (after)
Once, the executable has stoppped, we may also execute some other actions. But be careful of the fact that:
- we will pass through the //after()// method after clicking on the GExecButton (or the GExecMenuItem) ... that does not mean that the process is finished. So, we will use the getFinalnalSource() method (as explained in GListener interface section).
- the process may have stoppped nominally or because we stopped it before its end.
The example below shows how to manage this situation:
public void after(GEvent e) {
if ( e.getFinalSource() == cmd ) {
// We actually launched the application
if ( cmd.getProcessStatus() == ProcessStatus.FINISHED_NORMALY ) {
System.out.println("Computation nominally finished ...");
}
else if ( cmd.getProcessStatus() == ProcessStatus.FINISHED_BY_USER ) {
System.out.println("Computation stopped by user ...");
}
}
}
GProgressBar
Another interesting widget is GProgressBar to know the evolution of the computation process.
// Getting the progress bar from the cmd object
GProgressBar pBar = cmd.getGProgressBar();
// Calling corresponding swing object to resize it
pBar.getJProgressBar().setPreferredSize(new Dimension(250,30));
…
public void generic() throws GException {
put(cmd);
...
put(pBar); // Display as any other widget
}
…
public void display() throws GException { generic(); }
…
The computation program will send the information as this:
- Send on the standard output "@value@\n" with value between 0 and 100
- Or use GEnvironment.sendProgress(value) with value between 0 and 100
It is possible to force the value with the setValue(val) method.