Prozess mit Runtime.getRuntime in SwingWorker aufrufen

xyz123

Mitglied
Hallo,

mein Problem ist folgendes:
Ich habe ein Programm mit einer GUI, die GUI besteht gerade nur aus einem Button und wenn ich diesen Button drücke, soll ein Programm ausgeführt werden. z.B. Blast oder ein einfacher "ls"-Aufruf. Solange dieser Prozess aber dauert, soll der Button deaktiviert sein und sobald der Prozess fertig ist, soll der Button wieder aktivierbar sein.
Das Problem ist, dass der Button zwar deaktiviert wird, aber nicht mehr aktiviert wird.
Ich habe das mit SwingWorkers implementiert.
Außerdem möchte ich wissen, wann der Prozess startet und endet und diese Zeiten dann dem Hauptthread übergeben.

Wäre schön, wenn mal jemand drüberschaut.

Hier ist mein Code:
Java:
package blastgui;

import java.awt.EventQueue;
import javax.swing.JFrame;

public class BlastGui {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable(){

            public void run() {
                JFrame frame = new BlastFrame();
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }
}

Java:
package blastgui;

import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

class BlastFrame extends JFrame implements ActionListener, PropertyChangeListener{

    JButton buttonRun;
    Task task;

    public BlastFrame() {
        setTitle("Blast Test");

        buttonRun = new JButton("RUN");
        buttonRun.setActionCommand("run");
        buttonRun.addActionListener(this);

        JPanel panel = new JPanel();
        panel.add(buttonRun);
        add(panel);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getActionCommand().equals("run")){
            buttonRun.setEnabled(false);
            String cmd = "ls";
            task = new Task(cmd);
            //task.addPropertyChangeListener(this);
            task.execute();
        }
    }
}

Java:
package blastgui;

import javax.swing.JButton;
import javax.swing.SwingWorker;

public class Task extends SwingWorker<Void, Void>{
    String cmd;
    JButton button;
    GeneralInfo genInfo = new GeneralInfo();

    public Task(String command){
        cmd = command;
        button = new JButton("RUN");
    }

    @Override
    protected Void doInBackground() throws Exception {
        System.out.println("Startzeit: " + genInfo.getCurrentTime());
        Process pr = Runtime.getRuntime().exec(cmd);
        return null;
    }

    @Override
    public void done(){
        button.setEnabled(true);
    }
}
 

KrokoDiehl

Top Contributor
Also dass der Button nicht mehr aktiviert wird, liegt vermutl. daran, dass ein JButton in der Task-Klasse vorhanden ist. Das ist ja ein anderer als der im BlastFrame!
Um den Status des SwingWorker zu überwachen (zB um zu erfahren, wann er fertig ist), kannst du einen PropertyChangeListener dran hängen, der auf "state" reagiert (SwingWorker API).

Für dein anderes Problem gibt es die Methode
Code:
waitFor()
beim Process über über die Klase Calendar kannst du die aktuelle Systemzeit erfragen.
 

xyz123

Mitglied
Ach so, stimmt der Button wird in Blast neu angelegt.
Den PropertyChangeListener probiere ich dann mal aus.

Aber ich dachte mir, sobald die Aufgabe in doInBackground fertig ist, wird automatisch die done() Funktion aufgerufen. Oder hab ich die SwingWorkers falsch verstanden?

Dein Tipp mit der Uhrzeit probiere ich gleich mal aus.
 

KrokoDiehl

Top Contributor
Ja das kann sein, dass
Code:
done()
am Ende aufgerufen wird, so gut kenn ich's nicht. Aber dann hast du das Problem, dass du in
Code:
done()
nicht einfach so auf den Button zugreifen kannst. Mit der Listener-Methodik bekommt dein Frame die Info, der den Button kennt; Das ist sauberer, als dem SwingWorker eine Referenz zu übergeben, die ihm eigentl. egal sein sollte.
 

xyz123

Mitglied
OK, dann der PropertyChangeListener.
Der liefert state, sobald der Prozess fertig ist und sonst progress, richtig?

Versuch ich morgen.
 

KrokoDiehl

Top Contributor
Ehm, musst du mal prüfen was der liefert... einfach mal ein Durchgang mit
Code:
System.out.println()
laufen lassen ;)
Auswendig kenn ich das nicht.
 

Ähnliche Java Themen

Neue Themen


Oben