Hallo Leute,
eigentlich sollte es nicht so shwer sein, aber seit Tagen komme ich nicht klar. Ich möchte mit Runtime.getRuntime().exec einen Prozess starten. Dabei möchte ich einen JDialog zeigen, der mit einem unbestimmten (Indeterminate) JProgressBar dem Benutzer deutlich macht, dass der Prozess gerade läuft (Warte-Dialog). Und wenn der Prozess sich beendet hat, sollte auch der Dialog sich beenden.
Da, wenn ich den Dialog mit setVisible(true) sichtbar mache, mein Program an der Zeile hängen bleibt, habe ich versucht es mit einem Thread zu erledigen. Der Thread macht den Dialog sichtbar, danach starte ich den Prozess und wenn der Prozess sich beendet hat, soll mein Hauptthread den mit dispose() beenden.
Obwohl ich den Thread als erstes starte bzw. den Dialog als erstes sichtbar mache, bewegt sich der ProgressBar nicht, bis der Prozess sich beendet hat.
Nun, was kann ich tun, oder was mache ich falsch? Hoffentlich konnte ich es deutlich machen.
Hier sind meine Klassen ein mal für das Hauptfenster und einmal für den Dialog:
Klasse MainFrame:
Und Klasse ProzessVorgangDialog:
eigentlich sollte es nicht so shwer sein, aber seit Tagen komme ich nicht klar. Ich möchte mit Runtime.getRuntime().exec einen Prozess starten. Dabei möchte ich einen JDialog zeigen, der mit einem unbestimmten (Indeterminate) JProgressBar dem Benutzer deutlich macht, dass der Prozess gerade läuft (Warte-Dialog). Und wenn der Prozess sich beendet hat, sollte auch der Dialog sich beenden.
Da, wenn ich den Dialog mit setVisible(true) sichtbar mache, mein Program an der Zeile hängen bleibt, habe ich versucht es mit einem Thread zu erledigen. Der Thread macht den Dialog sichtbar, danach starte ich den Prozess und wenn der Prozess sich beendet hat, soll mein Hauptthread den mit dispose() beenden.
Obwohl ich den Thread als erstes starte bzw. den Dialog als erstes sichtbar mache, bewegt sich der ProgressBar nicht, bis der Prozess sich beendet hat.
Nun, was kann ich tun, oder was mache ich falsch? Hoffentlich konnte ich es deutlich machen.
Hier sind meine Klassen ein mal für das Hauptfenster und einmal für den Dialog:
Klasse MainFrame:
Code:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MainFrame extends JFrame implements ActionListener, Runnable
{
private static final long serialVersionUID = 1L;
private JButton starterButton;
private TextField textField;
private JPanel mainPanel;
private GridBagConstraints constraints;
private Process prozess;
private ProzessVorgangDialog prozessVorgangDialog;
public MainFrame()
{
super("ProzessStarter");
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
starterButton = new JButton("Prozess starten");
textField = new TextField("Textfeld nicht beachten", 16);
mainPanel = new JPanel();
prozessVorgangDialog = new ProzessVorgangDialog(MainFrame.this, "Bitte warten, Prozess läuft", true);
mainPanel.setLayout(new GridBagLayout());
constraints = new GridBagConstraints();
constraints.insets = new Insets(10,0,0,10);
constraints.fill = GridBagConstraints.VERTICAL;
mainPanel.add(textField, constraints);
constraints.gridy = 2;
mainPanel.add(starterButton, constraints);
starterButton.addActionListener(this);
getContentPane().add(mainPanel);
this.setVisible(true);
this.setSize(300, 300);
}
public void prozessAusfuehren()
{
try
{
prozess = Runtime.getRuntime().exec("cmd /C start C:\\Windows\\System32\\ping.exe 192.168.16.88");
// Damit mein Program wartet, solange der Prozess aktiv ist
leseProzessStream();
// stattdessen könnte waitFor() aufgerufen werden
// aber mit CMD Befehlen funktioniert es nicht
// mit direktem Exe-Aufruf schon
//try { prozess.waitFor(); }
//catch (InterruptedException e) { e.printStackTrace(); }
}
catch(IOException e)
{
System.out.println(e.toString());
}
System.out.println("prozessAusfuehren() beendet");
// Im Idealfall sollte unten der Dialog beendet werden.
// auskommentiert damit man sieht, dass der Dialog nach dem Prozess startet
//prozessVorgangDialog.dispose();
}
public void leseProzessStream()
{
BufferedReader in = new BufferedReader(new InputStreamReader(prozess.getInputStream()));
String s;
StringBuffer out = new StringBuffer();
try
{
while((s = in.readLine())!= null)
out.append(s + "\n");
}
catch (IOException e)
{
e.printStackTrace();
}
System.out.println(out.toString());
System.out.println("leseProzessStream() beendet");
}
@Override
public void actionPerformed(ActionEvent e)
{
(new Thread(this)).start();
prozessAusfuehren();
}
@Override
public void run()
{
prozessVorgangDialog.setVisible(true);
}
public static void main(String[] args)
{
new MainFrame();
}
}
Und Klasse ProzessVorgangDialog:
Code:
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JProgressBar;
public class ProzessVorgangDialog extends JDialog
{
private static final long serialVersionUID = 1L;
private JProgressBar progressBar;
public ProzessVorgangDialog(JFrame mainFrame, String title, boolean isModal)
{
super(mainFrame, title, isModal);
this.setSize(300,60);
this.setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
progressBar = new JProgressBar();
progressBar.setIndeterminate(true);
this.getContentPane().add(progressBar);
}
}