GUI und Threads



  • Hallo zusammen,

    irgendwie steh' ich grad verdammt auf dem Schlauch und hoffe, dass ihr mir vielleicht helfen könnt.

    Ich bin gerade dabei eine GUI zu basteln die folgendes tun soll.

    Im Hauptfenster gibt es einen Button, der wenn er gedrückt wird einen JFrame darstellen soll und ohne irgendeine weitere Aktion nötig wäre etwas bestimmtes macht - in diesem Fall Mails holen.
    Das Fenster allerdings wird nicht vollständig gezeichnet und es wird sofort die Aktion ausgeführt, was natürlich hässlich aussieht zumal ich eine ProgressBar sowie zusätzliche Statusinformationen einblenden möchte. Gut, jetzt hab' ich gedacht bastele ich aus der Aktion einen kleinen Thread der im Hintergrund arbeitet, so dass das Fenster genug Zeit hat sich zu zeichnen. Das klappt soweit auch ganz gut nur muss das Fenster mit der ProgressBar auf das Ende des Threads warten, damit es endgültige Informationen und Einstellungen machen kann bevor es wieder automatisch ausgeblendet wird. (Funktionsweise ähnlich wie dem aus Outlook Express - Send and Receive).

    Irgendwie wills nicht klappen - vielleicht hat jemand von Euch eine Idee?

    Danke schon mal



  • Hmm also so etwas meinte ich ...

    [java]package de.sahinc;

    import javax.swing.;
    import javax.swing.event.
    ;
    import java.awt.event.*;
    import java.awt.FlowLayout;

    public class Deneme extends JFrame {
    JFrame mainFrame = null;

    public Deneme() {
    super("Test for Multithreaded GUI");
    this.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    }
    });
    setSize(300, 200);
    JButton btn = new JButton("Start!");
    mainFrame = this;
    btn.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
    GUIClass gui = new GUIClass(mainFrame, false);
    Thread p = new Thread(gui);
    p.start();
    }
    });
    this.getContentPane().setLayout(new FlowLayout());
    this.getContentPane().add(btn);
    }

    public static void main (String args[]) {
    new Deneme().show();
    }
    }

    class GUIClass extends JDialog implements Runnable {
    JProgressBar progress = new JProgressBar(0, 100);

    public GUIClass(JFrame owner, boolean modal) {
    super(owner, modal);
    this.setTitle("GUIClass");
    this.getContentPane().setLayout(new FlowLayout());
    this.getContentPane().add(progress);
    pack();
    }

    public void run() {
    show();
    Thread p = new Thread(new WorkerThread(this));
    p.start();
    try {
    p.join();
    } catch (Exception ex) {
    ex.printStackTrace();
    }
    System.out.println("Ready!");
    dispose();
    }

    public void setValue(int val) {
    progress.setValue(val);
    }
    }

    class WorkerThread implements Runnable {
    GUIClass progressDialog = null;

    public WorkerThread(GUIClass dialog) {
    System.out.println("Init...");
    this.progressDialog = dialog;
    }

    public void run() {
    for (int i=0; i<100; i++) {
    progressDialog.setValue(i);
    try {
    Thread.sleep(100);
    Thread.yield();
    } catch (Exception ex) {
    ex.printStackTrace();
    }
    }
    }
    }[/code]

    Bitte um Eure Kommentare falls es eine bessere (elegantere) Lösung gibt - ich kopiers dann in die FAQ.

    Danke!



  • Probier doch einfach mal nicht aus dem Einen Thread (Im Dialog) den WorkerTHread aufzurufen, sondern direkt in der Klasse Deneme beide Thread zustarten. Dann sollten die relativ parallel laufen und auch nicht von einander abhängig sein.

    Ich bin mir nicht sicher, könnte aber eine Lösung sein!



  • Na ja eigentlich müssen sie voneinander abhängig sein, denn der Dialog mit der Progressbar wird nur so lange angezeigt wie der WorkerThread auch arbeitet (er zeigt ja den Fortschrittsbalken an). Ich habe dennoch versucht beide Threads von Deneme aus zu starten mit dem Ergebnis dass der Dialog viel zu schnell wieder geschlossen wird und somit nichts anzeigt.



  • Ich hab auch mal was Funktionstüchtiges zusammengeschustert. Was mir nur aufgefallen ist, ist dass man den Dialog nicht modal machen darf, denn dann startet der Thread erst nach dem Schließen des Dialogs.

    [java]
    import javax.swing.;
    import java.awt.event.
    ;

    public class ProgressBarExample extends JFrame implements ActionListener {

    ProgressBarExample() {
    super("ProgressBarExample");

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JButton btn = new JButton("Drück mich!");
    btn.addActionListener(this);

    getContentPane().add(btn);

    setSize(300, 200);
    setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
    new ProgressDialog(this);
    }

    public static void main(String[] args) {
    new ProgressBarExample();
    }

    class ProgressDialog extends JDialog implements Runnable {

    Thread t;
    JProgressBar b;

    ProgressDialog(JFrame owner) {
    super(owner, false);

    b = new JProgressBar(0, 100);
    getContentPane().add(b);

    setSize(200, 100);

    t = new Thread(this);
    t.start();
    }

    public void run() {
    setVisible(true);

    while(!t.isInterrupted() && b.getValue() < b.getMaximum()) {
    try {
    Thread.sleep(100);
    }
    catch(InterruptedException e) {
    e.printStackTrace();
    }
    b.setValue(b.getValue() + 1);
    }
    setVisible(false);
    dispose();
    }
    }
    }[/code]

    Man könnte nun noch eventuell abfragen ob, der Thread schon existiert, damit man nicht durch wildes Buttongeklicke mehrere Threads starten kann. Der Balken fängt dann jedoch immer von vorne an zu zählen.

    [ Dieser Beitrag wurde am 05.04.2002 um 11:18 Uhr von CengizS editiert. ]


Anmelden zum Antworten