ProgressBox - Update

tanechka

Bekanntes Mitglied
Hallo zusammen,

bei mir läuft der Update vom Progressbox nicht ordentlich.
So ist der bei mir aufgesetzt:
Code:
public void createProgressBar() {

        shell = new Shell(display, SWT.TITLE | SWT.PRIMARY_MODAL);     
        shell.setSize(491, 300);
        Device dev = shell.getDisplay();      

        setUpStatusBar();
        updateProgressBar();

      
        Monitor primary = display.getPrimaryMonitor();

        /** get the size of the screen */
        Rectangle bounds = primary.getBounds();

        /** get the size of the window */
        Rectangle rect = shell.getBounds();

        /** calculate the centre */
        int x = bounds.x + (bounds.width - rect.width) / 2;
        int y = bounds.y + (bounds.height - rect.height) / 2;

        /** set the new location */
        shell.setLocation(x, y);

    }

    private static void updateGUIInProgress(String statusText, int value, int count) {
        setStatus(statusText);
        progressBar.setMaximum(count);
        progressBar.setSelection(value);
    }

private static void setUpStatusBar() {
        progressBar = new ProgressBar(shell, SWT.SMOOTH);
        progressBar.setMaximum(0);
        progressBar.setBounds(65, 46, 354, 17);

        status = new Label(shell, SWT.NONE);
        status.setBounds(43, 77, 399, 71);
        status.setAlignment(SWT.CENTER);

        schliessenButton = new Button(shell, SWT.NONE);
        schliessenButton.setText("Schließen");
        schliessenButton.setVisible(true);
        schliessenButton.setBounds(177, 182, 131, 20);

        schliessenButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                shell.close();
            }
        });
    }

private void updateProgressBar() {

        Display.getDefault().asyncExec(new Runnable() {
            @Override
            public void run() {
                if (!progressBar.isDisposed())
                    try {           
                            // die erste Funktion
                           function1();
                           Thread.sleep(1000);
                          
                          // die zweite Funktion
                           function2();
                           Thread.sleep(1000);

                            updateGUIInProgress("Es ist durch...", 100, 100);                        

                    } catch (Exception e) {
                        logger.error(e);
                    }
            }
        });
    }

private void function1() throws Exception {
        updateGUIInProgress("function1", 43, 100);
      //Die Aufgabe 1
    }

private void function2() throws Exception {
        updateGUIInProgress("function2", 93, 100);
      //Die Aufgabe 2
    }
Mein Problem ist, dass der Progressbox nicht kontinuierlich upgedatet wird, während die function1() und funktion2() ausgeführt werden.
Wie könnte ich das so machen, dass während der Ausführungszeit von den Funktionen, der Progressbox automatisch weiterschreitet.

Vielen Dank
 

tanechka

Bekanntes Mitglied
Ich habe folgende Änderungen gemacht:
Code:
private  void updateProgressBar() {
        LongRunningOperation thread =new LongRunningOperation(display,progressBar);
        thread.start();
        function1();
        thread.interrupt();
    
    }

class LongRunningOperation extends Thread implements Runnable{
    private Display display;
    private int progress = 0;
    private static final int increment = 10;
    private ProgressBar progressBar;

    public LongRunningOperation(Display display,ProgressBar progressBar) {
        this.display = display;
        this.progressBar = progressBar;
    }

    public void run() {

        while (!progressBar.isDisposed()) {
            display.getDefault().asyncExec(new Runnable()
            {
                @Override
                public void run()
                {
                    if (!progressBar.isDisposed())
                        progressBar.setSelection((progress += increment) % (progressBar.getMaximum() + increment));
                }
            });

            try
            {
                Thread.sleep(1000);
            }
            catch (InterruptedException e)
            {
//                e.printstacktrace();
            }
        }
    }
}
Ich möchte den Progressbox so lange laufen lassen, bis die function1() läuft. Wenn die function1() fertig ist, möchte ich den Progressbox auf 100 % setzen. Mit den Änderungen läuft zwar der Progressbox, die function1() wird nicht ausgeführt:(
 

KonradN

Super-Moderator
Mitarbeiter
Sicher, dass die Methode nicht aufgerufen wird? Ich denke, dass die Methode durchaus aufgerufen wird.

Du hast ja den Ablauf, dass Du den neuen Thread startest. Direkt danach wird function1 aufgerufen.
So es noch die Methode ist, die Du mal gezeigt hast, wird da dann die progressBar gesetzt.
Parallel startet aber auch der Thread. Der ruft dann asyncExec auf, in dem dann auch die progressBar gesetzt wird.

Vermutlich ist der erste thread der UI Thread und das asyncExec führt etwas bei nächster Gelegenheit auf dem UI Thread aus. Dadurch kommt das zweite setzen des progressBar immer nach dem aus function1. Aber das alles kommt so schnell, dass Du da einfach nicht die Änderung siehst (So diese überhaupt angezeigt wird, denn durch die Veränderung kommt ja erst ein WM_PAINT Event in die Queue und der UI Thread muss dann erst das Fenster bzw. Controll neu malen. Und kann durchaus sein, dass das asyncExec generell vor dem WM_PAINT kommt. Das ist aber ein Detail, das keine Rolle spielt - ob da nun für wenige ms das Bild mal kurz angepasst war oder nicht dürfte keine Rolle spielen.
 

tanechka

Bekanntes Mitglied
Ja, hast du recht. Die Methode wurde aufgerufen.
Ich versuche den Progressbox auf 100 zu setzen, das klappt noch nicht.
Code:
    LongRunningOperation thread =new LongRunningOperation(display,progressBar);
        thread.start();
        function1();
        thread.interrupt();
        progressBar.setSelection(100);
Wo mache ich den Fehler? Der Progressbox läuft weiter. Ich habe angenommen, der Prozess wird abgebrochen.
 

KonradN

Super-Moderator
Mitarbeiter
Ich habe hier jetzt noch nicht wirklich verstanden, was Du genau machen willst. Nach meinem Verständnis hast Du eine Sache, die parallel zu dem UI Thread laufen soll. Und denn diese Sache fertig ist, dann soll etwas anderes passieren (hier die ProgressBar auf 100% setzen). Das sollte also in einem Thread ablaufen, in dem Du dann halt genau diese Dinge machst. Sprich: Du machst das, was Du machen willst, setzt dabei regelmäßig den Status und wenn Du fertig bist, dann setzt du zuletzt die ProgressBar auf die 100%.

Ich kenne SWT nicht - evtl. hast Du da auch sowas wie einen BackgroundWorker wie in Swing den SwingWorker. Das sind Klassen, die Dir mehrere Dinge bieten:
  • Es wird etwas in einem eigenen Thread ausgeführt.
  • Du hast eine Methode, mit dem du den Status aktualisieren kannst. Dazu hast du eine Methode, mit der Du den Status setzt und zum anderen einen Eventhandler, der dann im UI Thread ausgeführt wird
  • Du hast in der Regel etwas, das am Ende aufgerufen wird, wenn der BackgroundWorker seine Arbeit beendet hat (mit einem Ergebnis) - das fidnet dann auch auf dem UI Thread statt.

Damit hast Du keine runAsync Aufrufe oder so (Ich nehme an, das ist der Aufruf für die Ausführung auf dem UI Thread).


Zurück zu Deinem Code: Was ich sehe, ist ein Problem, dass der eine Thread so lange läuft, wie die ProgressBar noch aktiv ist (nicht disposed). Das ist ungünstig. Da sehe ich somit auch nicht, was da wirklich gemacht wird, denn der gezeigte Code setzt ja auch nur die ProgressBar. Ist dahinter kein Prozess? Ist das nur eine Art Wartezeit? Denn jede Sekunde veränderst Du da nur den Wert um ein increment wenn ich das so auf Anhieb richtig gesehen habe ...

Vielleicht beschreibst Du einfach einmal, was Du genau machen willst. Was genau soll passieren? Was für Dinge passieren, auf die Du reagieren willst?

Edit: ChatGPT meint, dass es in SWT keinen BackgroundWorker gibt wie in Swing den SwingWorker. Das nur als Hinweis, damit man da nicht unnötig Zeit in Recherchen steckt.
 

tanechka

Bekanntes Mitglied
Du hast schon recht, im Moment ist das eine Art Wartezeit. Wenn die function1() fertig ist, soll der Prozessbar auf 100 % gesetzt werden und der Dialog könnte geschlossen werden. Das ist die Theorie...im Moment läuft er weiter und der Code hat keine Wirkung:
Code:
thread.interrupt();
progressBar.setSelection(100);

Angedacht ist, dass ich zwei Methoden ausführe. Optimal wäre für mich ein Update vom Status nach jedem Methodenaufruf.
 

KonradN

Super-Moderator
Mitarbeiter
Wenn es nur darum geht, dass Du eine gewisse Zeit warten willst, dann kannst Du das doch prinzipiell so aufsetzen:

Du brauchst nur den Thread LongRunningOperation (der dann evtl. "WaitingThread" heissen sollte oder so).

Der braucht ein paar Parameter, wie z.B.:
  • die ProgressBar
  • die Anzahl der Schritte
  • die Wartezeit pro Schritt.

In dem Thread machst Du dann einfach folgenden Pseudo Code:
1. Schrittnummer := 0
2. Schleife so lange Schrittnummer < Anzahl Schritte
2.1. setze progressBar auf Maximum / Anzahl Schritte * Schrittnummer
2.2. warte Wartezeit
2.3. Schrittnummer++
3. Setze ProgressBar auf Maximum
4. Mach das Fenster schließbar.

Der Thread endet nach der Wartezeit automatisch. Also keine Prüfung auf disposed oder so. Die kannst Du natürlich mit als Check drinnen lassen, falls das Fenster doch irgendwie geschlossen wurde oder so.

Wichtig: Jede Veränderung an der UI sollte über asyncExec auf dem UI Thread erfolgen. Aber statt da immer mit inneren Klassen zu arbeiten, kannst Du es einfach per Lambda Expression machen. Also etwas wie:
display.getDefault().asyncExec( () -> progressBar.setSelection(calculatedValue) );
Das macht den Code deutlich kürzer und lesbarer :)

Edit:
  • an der Stelle noch der dezente Hinweis: Ich habe nie mit SWT gearbeitet. Ich habe hier also Dinge von Deinem Code abgeschaut. Ob dies korrekt oder der übliche Weg ist, kann ich daher nicht sagen. Aber ich hoffe, ich konnte Dir helfen.
  • ebenfalls wichtig: Lambda Expression / Methodenreferenz funktioniert übrigens auch sehr gut bei einem Thread. Man muss nicht von Thread erben sondern man kann da auch new Thread(Runnable) nutzen und eine Methodenreferenz als Runnable angeben. Also etwas wie
new Thread(this::updateProgressbarOverTime).start() oder so mit einer Methode void updateProgressbarOverTime() in der die skizzierte Logik implementiert wurde und die genannten Parameter werden nicht gegeben sondern die Werte sind in Instanzvariablen.
 
Zuletzt bearbeitet:

tanechka

Bekanntes Mitglied
Das Problem ist, ich weiß nicht genau wie lange es geht. Es könnte schnell sein, es könnte auch dauern. Deswegen wollte ich einen Update vom Status nach jeder Methode machen, so dass man weiß, wo man gerade ist.
 

tanechka

Bekanntes Mitglied
Ich habe jetzt mit dem Code den Progressbar terminiert:
Code:
public void updateProgressBarWhenFinish() {
        display.asyncExec(new Runnable() {
            @Override
            public void run() {
               
                progressBar.setSelection(0);
                progressBar.setMaximum(1);
               
            }
        });
    }
 

tanechka

Bekanntes Mitglied
Vielen Dank für die Hilfe. Ich habe mittlerweile viel geändert. Meine function1() und function2() sind jetzt in der run()-Funktion des Threads.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
Ernesto95 JavaFX JavaFX GUI mit sehr vielen Update requests AWT, Swing, JavaFX & SWT 4
G update, paintComponent AWT, Swing, JavaFX & SWT 1
T GUI Update /EDT AWT, Swing, JavaFX & SWT 7
izoards JavaFX Concurrency Update UI AWT, Swing, JavaFX & SWT 35
ms_cikar Update swingUtilities Repaint in der Schleife AWT, Swing, JavaFX & SWT 3
J TableView Update/Refresh CPU AWT, Swing, JavaFX & SWT 2
A Verständnisfragen im Umgang mit update() und JFrames AWT, Swing, JavaFX & SWT 5
ralfb1105 Swing JComboBox update der Daten AWT, Swing, JavaFX & SWT 8
blazingblade JavaFX Tableview Clock Column update AWT, Swing, JavaFX & SWT 5
R Update eines Labels bei Methodenaufruf einer anderen Klasse AWT, Swing, JavaFX & SWT 9
B Swing Update Swing Komponente bevor Methode startet. AWT, Swing, JavaFX & SWT 4
M JavaFX ComboBox: Update zur Laufzeit AWT, Swing, JavaFX & SWT 16
W Swing ProgressBar update AWT, Swing, JavaFX & SWT 4
B IconImage update im Tabbedpane AWT, Swing, JavaFX & SWT 3
M Update überschreiben klappt nicht AWT, Swing, JavaFX & SWT 4
Q JList Update Problem AWT, Swing, JavaFX & SWT 1
N Observer: update ruft nicht repaint auf AWT, Swing, JavaFX & SWT 0
M "Update" der JTable funktioniert nicht AWT, Swing, JavaFX & SWT 2
S Swing Update eine JTabelle nach einer Drag&Drop Operation AWT, Swing, JavaFX & SWT 0
C Swing Update von swing-TableModels per Thread. Eins geht, das andere nicht, warum? AWT, Swing, JavaFX & SWT 12
V Swing Update Textarea AWT, Swing, JavaFX & SWT 2
T Event Handling JFreeChart Update AWT, Swing, JavaFX & SWT 2
Farbtopf Live update JFreeChart AWT, Swing, JavaFX & SWT 3
F Swing GUI-Thread für automatisches Update nutzen AWT, Swing, JavaFX & SWT 10
El_Lobo Swing bei Update von Graphik Koordinatensystem nicht jedesmal neu zeichnen AWT, Swing, JavaFX & SWT 2
M Update JPanel AWT, Swing, JavaFX & SWT 12
N update model nach dem filtern AWT, Swing, JavaFX & SWT 2
E Umgang mit der Update Methode AWT, Swing, JavaFX & SWT 38
E Swing Update JTable AWT, Swing, JavaFX & SWT 6
L Update JTree Verzeichnisse AWT, Swing, JavaFX & SWT 9
G Swing Update-Funktion für Swing-Anwendung AWT, Swing, JavaFX & SWT 5
E Swing JTextField Listener nach Update?! AWT, Swing, JavaFX & SWT 2
D Swing JTable Problem bei automatischem update von Zellen AWT, Swing, JavaFX & SWT 3
P 2D-Grafik PaintComponent() übernimmt keine Werte aus update() AWT, Swing, JavaFX & SWT 8
D Swing update eines Labels nicht sichtbar AWT, Swing, JavaFX & SWT 9
N Tablle nach SQL-Update neu Laden AWT, Swing, JavaFX & SWT 4
M SWT grabExcessHorizontalSpace update ? refresh ? AWT, Swing, JavaFX & SWT 6
P Observer und GUI Update AWT, Swing, JavaFX & SWT 2
w0ddes Swing Update: Laufendes GUI updaten AWT, Swing, JavaFX & SWT 8
D JTable während edit kein update machen lassen AWT, Swing, JavaFX & SWT 2
M Swing Kein update bei simulierten HTML-Link AWT, Swing, JavaFX & SWT 4
C SWT Shell update probleme - Mausbewegung nötig AWT, Swing, JavaFX & SWT 2
hdi Swing GUI update vs. Process Speed AWT, Swing, JavaFX & SWT 31
hdi Swing Gui Update Problem (EDT) AWT, Swing, JavaFX & SWT 6
C JList update über tabbedPane? AWT, Swing, JavaFX & SWT 18
M Update einer JTEextArea AWT, Swing, JavaFX & SWT 2
H JTable mySQL Update AWT, Swing, JavaFX & SWT 8
S Update des fensters beim Ersetzen von JPanels AWT, Swing, JavaFX & SWT 9
G Features nach Update löschen AWT, Swing, JavaFX & SWT 2
J Fragen zur Vererbung und Update AWT, Swing, JavaFX & SWT 12
B Update von JLabels AWT, Swing, JavaFX & SWT 2
C Habe Probleme beim Bild laden! *Update 30.11.2006* AWT, Swing, JavaFX & SWT 28
C JTreeTable update Problem AWT, Swing, JavaFX & SWT 4
S Probleme mit dem Update einer JList AWT, Swing, JavaFX & SWT 7
B View zeichnet Daten aus dem Model ohne Update AWT, Swing, JavaFX & SWT 4
A Update von Frameinhalt und Scrollbar AWT, Swing, JavaFX & SWT 11
F MVC: Update von View und Controller AWT, Swing, JavaFX & SWT 5
C JTable update: Selektion beibehalten AWT, Swing, JavaFX & SWT 12
P paintComponent /paint/ update/ offscreenImage / Graphics2D / AWT, Swing, JavaFX & SWT 4
S JMenuBar + update AWT, Swing, JavaFX & SWT 3
G JTree - ungültiger selection update AWT, Swing, JavaFX & SWT 2
G Problem mit JLabel Update AWT, Swing, JavaFX & SWT 3
C [JTable] Update der Datenbank AWT, Swing, JavaFX & SWT 6
N update()-Methode für Canvas AWT, Swing, JavaFX & SWT 9
A problem mit update nach event, JSplitpane spinnt AWT, Swing, JavaFX & SWT 2
S Update von Grafik auf JPanel AWT, Swing, JavaFX & SWT 2
M GUI Update während der Verarbeitung einer Methode AWT, Swing, JavaFX & SWT 3
M update JTable AWT, Swing, JavaFX & SWT 3
T Problem bei Update von JTables in JTabbedPane AWT, Swing, JavaFX & SWT 2
D Problem beim Update von unsichtbaren JComponents mit Timern AWT, Swing, JavaFX & SWT 5
D Swing: GUI-Update-Problem AWT, Swing, JavaFX & SWT 3
J Warum funktioniert das Update des UI nicht? AWT, Swing, JavaFX & SWT 8
I GUI-Update-Probleme AWT, Swing, JavaFX & SWT 2
G Update von JPanel nach Buttonbetätigung AWT, Swing, JavaFX & SWT 1

Ähnliche Java Themen

Neue Themen


Oben