Swing Splash Screen Prozentanzeige

Danloc

Mitglied
Hallo,

ich bin noch Programmieranfänger und habe mich an mein erstes GUI Projekt gemacht.
Leider habe ich ein Problem, welches ich mir nicht erklären kann.

Ich habe ein Programm, welches aktuell aus 2 Klassen besteht, die wiederrum die beiden Forms "repräsentieren". Mein Ziel ist es, nach einem Klick auf den Button, dass eine Fenster zu schließen und das "zweite" Fenster anzuzeigen. Soweit so gut - dass funktioniert auch!

Jetzt habe ich auf dem "zweiten" Fenster ein Label hinzugefügt, dessen Text ich von 1 - 100 hochzähle, um eine "Ladeanzeige" in Prozent zu simulieren. Mein Problem ist aber, dass sich das Fenster erst öffnet, nachdem die Schleife durchgelaufen ist. Es poppt also nach ein paar Sekunden direkt mit der Aufschrift 100% auf. Das Fenster bleibt für die Zeit, des hochzählens unsichtbar.

Hier mal mein code, wie ich versucht habe es umzusetzten.

Hauptfenster, welches den Button besitzt, um das zweite Fenster zu aktivieren:
Java:
    private void ButtonLoginActionPerformed(java.awt.event.ActionEvent evt) {                                           
        String Benutzertext = Benutzername.getText();
        String Passworttext = String.valueOf(Password.getPassword());
       
       
        if (Benutzertext.equals("a") && Passworttext.equals("a") {       
            willkommen welcomescreen = new willkommen();
            setVisible(false);
            welcomescreen.AngezeigterText(Benutzertext);
            welcomescreen.setVisible(true);
        }else {
            ErrorMessage.setEnabled(true);
            ErrorMessage.setText("Benutzername oder Passwort falsch! Bitte erneut versuchen.");
        }       
    }

Zweites Fenster, welches sich mit der "Prozentanzeige" öffnen soll:
Java:
        public void AngezeigterText (String text) {
       
        willkommentext.setText("Willkommen, " + text);
        LoadingPercent();
    }
   
       
       
       public void LoadingPercent () {
       
        try {
        for (int i = 0; i <= 100; i++) {
           
            Thread.sleep(40);
            LoadingNum.setText(Integer.toString(i)+"%");
            }
        } catch (Exception e) {
           
        }
       
    }

Ich habe auch versucht, die Methode "LoadingPercent" des zweiten Fensters innerhalb der ersten Klasse, mittels der Button Action aufzurufen. Der Effekt bleibt der gleiche.
Hat jemand eine Idee was ich falsch mache?

Danke schonmal..

Grüße Danloc
 
Thread.sleep(..) lässt den aktuellen Thread einfrieren. In deinem Fall ist das der EDT und deshalb blockiert auch deine GUI.
Lagere die Schleife samt Thread.sleep in einen neuen Thread aus.
 
Danke für die schnelle Antwort.
Wie könnte sowas denn aussehen?
Müsste ich dazu eine neue Klasse erzeugen, von der ich dann ein Objekt erzeuge, indem ich wiedderum ein sleep mache? 😵
falls ja, erscheint mir das sehr umständlich .. gibt es vielleicht bessere oder andere Lösungsansätze - Es soll ja "nur" die Zahl hochgezählt und hinterher noch eine Progressbar dran geknüpft werden. ( In dem Beispiel von dem ich es habe, schreibt er alles in die main und sein fenster öffnet sich trotzdem ... ?

Bei google, sind die meisten Beispiele zu diesem Thema sehr komplex und auch nicht wirklich passend zu meinem Problem.. Bin damit etwas überfordert .. sorry
 
Hallo.

Java:
new Thread() {
  @Override public void run() {
    try {
      Thread.sleep( 2000 );
      System.out.println( "Zeit ist um." );
    } catch ( InterruptedException e ) { e.printStackTrace(); }
  }
}.start();

Das ist doch nicht umständlich 🙂

Grüße
 
Hallo und danke für den Tipp,

ich habe mich nochmal etwas reingelesen und es gelöst.
Es funktioniert auch genau so wie truesoul beschreibt. Ich habe 2 Möghlichkeiten den Thread zu erzeugen ausprobiert. Und teile meine Lösung, falls nochmal jemand ein solches Beispiel benötigt

Zum einen kann der Thread direkt im Konstrukor erzeugt werden, indem mittels run methode eben der gewünschte code ausgeführt wird. So würde der code in der run methode bei jedem mal ausgeführt, wenn ein Objekt von dieser Klasse erzeugt wird:
Java:
public class willkommen extends javax.swing.JFrame {

    public willkommen() {
        this.t1 = new Thread(new Runnable() {
            @Override
            public void run () {
                try {
                    for (int i = 0; i <= 100; i++) {
                       
                        Thread.sleep(15);
                        LoadingNum.setText(Integer.toString(i)+"%");
                        LoadingBar.setValue(i);
                    }
                   
                } catch (InterruptedException e) {
                    //some error handling ...
                }
               
            }
        });
        initComponents();
    }


Oder man erstellt einen neuen Thread und starten diesen von einer Methode:
Java:
    public void AngezeigterText (String text) {
       
        willkommentext.setText("Willkommen, " + text);
        t1.start();
    }
   
             
    Thread t1 = new Thread(new Runnable() {
    @Override
        public void run () {
            try {
                for (int i = 0; i <= 100; i++) {
           
                    Thread.sleep(15);
                    LoadingNum.setText(Integer.toString(i)+"%");
                    LoadingBar.setValue(i);
                }
               
            } catch (InterruptedException e) {
                  //some error handling ...
            }
         
        }
    });

Ich denke es ist vom Anwendungsfall abhängig, welche der Beiden Varianten man wählt. Kritik oder weitere Ergänzungen, falls ich etwas falsch erläutert habe sind immer gern gesehen.

In diesem Sinne, danke für die Anregungen 🙂

Grüße Danloc
 

Zurück
Oben