how can I execute a process in Java without the program freezing? I've tried using SwingWorker, but I don't quite yet understand how it works.
Is there any other way I can accomplish this?
Thanks in advance!
EDIT:
Thanks for your answers. But I have a class with several methods (well, it's more than one class, but you get my point); how can I use a SwingWorker to interact with those?
Here is one of the classes:
/**
*
* @author Simon
*/
public abstract class Command extends SwingWorker {
BufferedReader prReader = null;
ProcessBuilder process = null;
Process pr = null;
Date timeNow = new Date();
String osName = System.getProperty("os.name");
public void executeProcessNoReturn(String _process, String arg) throws IOException {
process = new ProcessBuilder(_process, arg);
pr = process.start();
}
public String executeProcessReturnLastLine(String _process, String arg) throws IOException {
process = new ProcessBuilder(_process, arg);
pr = process.start();
prReader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line;
while ((line = prReader.readLine()) != null) {
// Wait for input to end.
}
return line;
}
public StringBuilder executeProcessReturnAllOutput(String _process, String arg) throws IOException {
process = new ProcessBuilder(_process, arg);
pr = process.start();
prReader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
StringBuilder output = null;
String line;
while ((line = prReader.readLine()) != null) {
output.append(line);
}
return output;
}
public boolean isProcessRunning(String processName) throws IOException {
boolean value = false;
if (osName.equals("Linux") | osName.contains("Mac")) {
process = new ProcessBuilder("ps", "-e");
pr = process.start();
String line;
prReader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
while ((line = prReader.readLine()) != null) {
if (line.contains(processName)) { value = true; break; }
}
} else {
String winDir = System.getenv("windir") + "/System32/tasklist.exe";
process = new ProcessBuilder(winDir);
pr = process.start();
String line;
prReader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
while ((line = prReader.readLine()) != null) {
if (line.contains(processName)) { value = true; break; }
}
}
return value;
}
public String executeProcessReturnError(String processName, String arg) throws IOException {
process = new ProcessBuilder(processName, arg);
process.redirectError();
pr = process.start();
prReader = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
String line;
String output = "";
while ((line = prReader.readLine()) != null) {
output += line + "\n";
}
return output;
}
}
Yes you can use a SwingWorker
the idea is that a task that takes a lot of time you run in a separate thread (background thread) then you don't block your gui and your JFrame is not gonna to freeze. Here is a complete example i really like Swing Worker Example.
Basically as an example you create your own class that extends SwingWorker
override doInBackground
.
NOTE: You can have fields like a normal class.
Example :
class Worker extends SwingWorker<Void, String> {
private SomeClass businessDelegate;
private JLabel label;
@Override
protected Void doInBackground() throws Exception {
//here you make heavy task this is running in another thread not in EDT
businessDelegate.callSomeService();
setProgress(30); // this is if you want to use with a progressBar
businessDelegate.saveToSomeDataBase();
publish("Processes where saved");
return null;
}
@Override
protected void process(List<String> chunks){
//this is executed in EDT you can update a label for example
label.setText(chunks.toString());
}
//add setters for label and businessDelegate
}
You also read about process(..)
publish(..)
and done()
.
And in your client code just put.
SwingWorker<Void,String> myWorker = new Worker();
myWorker.execute();