ProgressBar/Ladestatus definieren

FHWS

Mitglied
Hallo Zusammen,
momentan bin ich dabei meine progressBar mit Leben zu füllen. Kurzer Hintergrund:
Ich habe ein Regal in welchem ich 32 Boxen einlagern kann. Hierfür habe ich eine SQL-Datenbank erstellt in welcher die Boxen aufgelistet sind. Ich möchte nun mit dem Zugriff auf die Datenbank in meiner progessBar den "Belegungsstatus" anzeigen. Sprich ich möchte das in meiner Datenbank die Anzahl der Boxen gezählt wird und mir dann bei z.B. 32 gefundenen Boxen der Status "100" angezeigt wird. Die Verknüpfung zur Datenbank funktioniert. Allerdings stehe ich auf dem Schlauch wie ich das ganze korrekt umsetzten kann. Für Tipps bin ich sehr dankbar! LG

Hier meine bisherige Programmierung
Java:
// Prozessbar Parameter
       
        progressBar.setStringPainted(true);
        progressBar.setBounds(200, 20, 200, 25);
        progressBar.setEnabled(true);
       
       
        progressBar.setValue((Box_Nr/32)*100);
        String Box_Nr;
            try {
               
               
                    Class.forName("org.mariadb.jdbc.Driver");    //Treiber für ODBC
                    conn = DriverManager.getConnection("jdbc:mariadb://fm-s012mp.fhws.de","Java","1234");
                    System.out.println("Erfolgreich verbunden");   
                   
                    abfrage = conn.createStatement();
                    result = abfrage.executeQuery(
                    "COUNT `Box_Nr`  FROM `lagersystem_test`.`00_hauptdatenbank` ");
                   
                   
                    while (result.next() == true) {
                       
                        String Box_Nr = result.getString("Box_Nr");
                    }       
                   
                    result.close();
                    abfrage.close();
                    conn.close();
                    System.out.println(result);
                }
               
             catch (InterruptedException e) {
                e.printStackTrace();
            }
       
       
       
        add(progressBar);
        progressBar.repaint();
:
 

FHWS

Mitglied
Der Ladestatus zeigt immer 100 % an. Es wird also nicht die korrekte Auslastung angezeigt.
In unten stehender Zeile unterstreicht eclipse mir auch den String...
Code:
                        String Box_Nr = result.getString("Box_Nr");
 

stg

Top Contributor
Java:
progressBar.setValue((Box_Nr/32)*100);
String Box_Nr;
Hier verwendest du die Variable Box_Nr noch bevor sie initialisiert wurde.
Außerdem teilst du "String durch Integer".

In unten stehender Zeile unterstreicht eclipse mir auch den String...
Code:
                        String Box_Nr = result.getString("Box_Nr");
Das liegt daran, da du innerhalb der While-Schleife eine neue Variable "Box_Nr" anlegst, welche die zuvor definierte Variable von weiter oben verdeckt. Nach jedem Schleifendurchlauf schmeißt du diese neue Variable samt Wert, den du zuvor ausgelesen hast, ungenutzt weg. Das ist sicherlich nicht das, was du machen möchtest.
Warum verwendest du überhaupt eine while-Schleife? Dein Query gibt doch genau eine Zeile zurück...
 

FHWS

Mitglied
Das mit der While-Schleife verstehe ich noch, jedoch macht er mir die Abfrage immer noch nicht...
Was muss ich den konkret noch anpassen?

LG
 

FHWS

Mitglied
Sorry jetzt bin ich raus... Das ist nun mein aktueller Stand:

Code:
// Prozessbar Parameter
       
        progressBar.setStringPainted(true);
        progressBar.setBounds(200, 20, 200, 25);
        progressBar.setEnabled(true);
       
        add(progressBar);
        progressBar.repaint();
       
   
        float Box_Nr;
            try {
               
               
                    Class.forName("org.mariadb.jdbc.Driver");    //Treiber für ODBC
                    conn = DriverManager.getConnection("jdbc:mariadb://fm-s012mp.fhws.de","Java","wildewalnuss");
                    System.out.println("Erfolgreich verbunden");   
                   
                    abfrage = conn.createStatement();
                    result = abfrage.executeQuery(
                    "COUNT `Box_Nr`  FROM `lagersystem_test`.`00_hauptdatenbank` ");
       
                    while (result.next() == true) {
                       
                        Box_Nr = result.getInt("Box_Nr");
                    }       
                }
               
             catch (InterruptedException e) {
                e.printStackTrace();
            }
       
        progressBar.setValue(((Box_Nr/50)*100));


Könnt Ihr mir bitte direkt im Code die Anmerkungen geben, ich glaub sonst komm ich vom Schlauch nicht runter.

LG
 

truesoul

Top Contributor
Die Schleife benötigst du nicht.
Und du könntest den Debugger doch auch verwenden.
Schaue was Box_Nr für ein Wert hat nach result.getInt()

Wo initialisierst du deine progressBar?
 

Neumi5694

Top Contributor
Wo legst du eigentlich fest, dass 100 der maximale Wert der Progressbar ist?
Fang klein an. Setz die Bar mal manuell ohne Zähler auf 50%. Erst danach denke an die DB.

Dann ist noch eines zu beachten: Es könnte auch einfach so sein, dass dein GUI-Thread blockiert wird. Das lässt sich anhand des Code-Ausschnitts nicht erkennen.
Wenn deine Logik z.b. von einem Button aus aufgerufen wird, dann wird die UI erst dann neu gezeichnet, wenn alles, was beim Klick passieren soll, abgearbeitet wurde. Am Ende hat die Bar natürlich 100% und das ist dann auch das Einzige, was du siehst, da die Zwischenschritte nie gezeichnet wurden.

Wenn ich so was wie eine Fortschrittsanzeige oder ein Echtzeit-Log haben will, dann pack ich den Ablauf immer in einen eigenen Thread.

https://docs.oracle.com/javase/tutorial/uiswing/components/progress.html
Das ist ein ganz anständiges Tutorial mit Beispielprogramm, schau mal rein.
 

FHWS

Mitglied
Hallo Zusammen,

ich bin nun nochmals auf das Problem zurückgekommen. Kurz nochmal was ich eigtl. vor habe. Ich möchte aus meiner Datenbank die Anzahl der Zeilen herauslesen, welche nicht Null sind. Die Anzahl der Zeilen z.B. 20 sollen dann als Ladestatus z.B. 50 % bei insgesamt 40 Zeilen anzeigt werden.
Bekomme jetzt allerdings im letzten Teil beim eigentlichen "Berechnen" des Wertes einen Fehler. Der Fehler ist im Skript markiert. Kann mir einer sagen wo der Fehler liegt?
Dankeee :)

Code:
        progressBar.setStringPainted(true);
        progressBar.setBounds(200, 20, 200, 25);
        progressBar.setEnabled(true);
       
        add(progressBar);
        progressBar.repaint();
       
       
        float  Wert;
           
            try {

                  Class.forName("org.mariadb.jdbc.Driver");

                        Connection con = java.sql.DriverManager.getConnection("jdbc:mariadb://fm-s012mp.fhws.de","Java","XXX");

                        Statement s = con.createStatement();

                        ResultSet res;

                        res = s.executeQuery("SELECT COUNT (*) AS anzahl FROM `lagersystem_test`.`00_hauptdatenbank` WHERE Boxinhalt IS NOT NULL" );

                        while (res.next()) {

                              System.out.print(res.getString("anzahl") );
                              Wert = result.getInt("anzahl");
                             
                        }

                  }

                  catch (Exception e) { System.out.println(""+e.getMessage());}

            int prozent = (int) ((Wert/35)*100); // Hier wird der Fehler bei "Wert" angezeigt
           
            progressBar.setValue(prozent);
 

Neumi5694

Top Contributor
ps: Zu deinem ursprünglichen Problem. Innerhalb der Schleife setzt du die Progressbar nicht, du machst das erst ganz zum Schluss, wenn alles erledigt ist oder durch einen Fehler abgebrochen wurde.

Wenn kein Datensatz eingelesen werden konnte, dann hat "Wert" niemals einene Wert.
ps: Variablennamen schreibt man klein.
 

Neumi5694

Top Contributor
Zeig mal, was du bisher erreicht hast.
Hast du das Ganze schon mal in einen Thread gepackt? Wie gesagt, deine Oberfläche wird erst neu gezeichnet, sobald der GUI-Thread abgelaufen ist. Und wenn du die Daten während des GUI-Threads einliest, dann wird nur das letzte Ergebnis angezeigt.

ps: Ich hab mich beim Lesen deines Codes vertan, bei dem, was ich gesehen hab, liest du ja gar keine Daten ein. Mein Fehler.
Poste doch nochmal, was du bisher hast.
 

Neumi5694

Top Contributor
Nach diesem Schema sollte es gehen.
Warte NICHT auf den Thread mit join(), sonst wird deine Progressbar wieder nicht angzeigt.
Merke: Auch "repaint" wird erst dann ausgeführt, wenn Methode des Buttons oder Menüs abgearbeitet ist.
Man kann da über die EventQue eingreifen, aber ein eigener Thread ist sinnvoller.

Java:
    public static void aButtonWasClicked() {
        displayProgressBarInGUI();
        Thread dbthread = new Thread() {
            @Override
            public void run() {
                lockGUI();
                int nRecordSets = 0;
                setProgressBarTo(0);
                try (Connection con = DriverManager.getConnection("jdbc:mariadb://fm-s012mp.fhws.de", "Java", "XXX");
                        Statement s = con.createStatement();) {
                    try (ResultSet res = s.executeQuery("SELECT COUNT (*) AS anzahl FROM "
                            + "`lagersystem_test`.`00_hauptdatenbank` WHERE Boxinhalt IS NOT NULL")) {
                        if (res.next()) {
                            nRecordSets = res.getInt(1);
                        }
                    }
                    if (nRecordSets <=0) {
                        return;
                    }
                    setProgressBarMaximum(nRecordSets);
                    int counter = 0;
                    setProgressBarTo(counter);
                    try (ResultSet res = s.executeQuery(readDataSqlString)) {
                        while (res.next()) {
                            readData(res);
                            setProgressBarTo(++counter);
                        }
                    }
                } catch (SQLException exp) {
                    //something bad happened. React accordingly
                } finally {
                unLockGUI();
            }
        };
        dbthread.start();
    }



Anm: Die Progressbar in diesem Beispiel hat nicht den maximalen Wert 100, sondern den der Anzahl der Datensätze.
Willst du eine Prozentanzeige, dann ist natürlich die Obergrenze stets 100, der Wert wirg gesetzt auf
Code:
(int)Math.floor(((double)++counter)/nRecordSets))
 

mihe7

Top Contributor
Anm: Die Progressbar in diesem Beispiel hat nicht den maximalen Wert 100, sondern den der Anzahl der Datensätze.
Ich glaube, er will etwas wesentlich einfacheres. Es soll nicht den Fortschritt des Lesens aus der Datenbank angezeigt werden sondern einfach nur, wie viele seiner Boxen belegt sind.
  1. Anzahl der Boxen gesamt:
    Java:
    final String totalCount = "SELECT count(*) FROM `lagersystem_test`.`00_hauptdatenbank`"
  2. Anzahl der gefüllten Boxen:
    Java:
    final String usedCount = totalCont + " WHERE Boxinhalt IS NOT NULL"
Damit
Java:
int total = get(totalCount);
int used = get(usedCount);
setProgressBarMaximum(total);
setProgressBarTo(used);

Update: sehe gerade, dass er den Prozentsatz der belegten Boxen anzeigen will. Dann wäre es natürlich: setProgressBarMaximum(100); setProgressBarTo((int)(used*100)/total);
 

FHWS

Mitglied
Hallo Zusammen,

ich habe jetzt mein Vorhaben etwas abgespeckt. Ich möchte neben meiner GUI mit einer Nebenklasse die Zählung der belegten Boxen durchführen. Die Zählung funktioniert soweit, bekomme für die Variable "anzahl" den richtigen Wert. Die Variable "anzahl" möchte ich nun in meiner GUI lediglich in ein Textfeld reinschreiben, dass da z.B. nur 30 steht mehr nicht. Ich tu mir allerdings grade sehr schwer die Variable aus der Nebenklasse in meine GUI zu bekommen?!?! Stehe da grade völlig neben der Spur...

Nebenklasse:
Java:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import javax.swing.JLabel;


import java.sql.DriverManager;

public class Count {

   
   
    static Connection conn;
    static Statement eintrag;
    static Statement eintrag2;
    static String ausgabe;
    Statement abfrage;
    int i;
    ResultSet res;
   
   
   
   
    Count() {
       

       
        try {

              Class.forName("org.mariadb.jdbc.Driver");

                    Connection con = java.sql.DriverManager.getConnection("jdbc:mariadb://fm-s012mp.fhws.de","Java","xx");

                    Statement s = con.createStatement();

                    ResultSet res;

                    res = s.executeQuery("SELECT COUNT (*) AS anzahl FROM `lagersystem_test`.`00_hauptdatenbank` WHERE Boxinhalt > '0'" );

                    while (res.next() == true) {

                          System.out.print(res.getString("anzahl") );
                 
                        
                       
                         
                         
                    }

                    res.close();
                    s.close();
                    con.close();

              }

              catch (Exception e) { System.out.println(""+e.getMessage());}

           }

        }

Ausschnitt GUI:

Java:
        textPB1 = new JLabel("XXX"); // hier soll die anzahl rein
        textPB1.setBounds(200, 10, 400, 25);
        textPB1.setVisible(true);
        add(textPB1);

Danke für Tipps!
 

Neumi5694

Top Contributor
1. Die Klasse Count kriegt ein Feld namens "anzahl" (private int-Klassenvariable + öffentliche getAnzahl()-Methode)
2. Dieser Wert wird dort gesetzt, wo du zur Zeit System.out stehen hast.
3. Den Wert rurfst du dann so ab
Java:
Count counter = new Count(); //die Variable wird in deinem Code im Konstruktor gesetzt. Falls du daran was änderst, musst du dann hier die entsprechende Methode aufrufen.
label.setText(String.format("%d", counter.getAnzahl())); //machen wir es mal ordentlich, setText("" + counter.getAnzahl()) würde bei so was einfachem natürlich auch funktionieren.

Tip: Setze Anzahl bei der Deklaration auf -1 oder einen anderen ungültigen Wert, dann siehst du beim Aufruf von getAnzahl() sofort, ob der Wert überhaupt gesetzt wurde.

ps: Mein Beispiel oben war zwar zu aufwendig, darin siehst du aber, wie du try-with-Resourcen verwendest.
https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Diese sind ganz praktisch, am Ende des Blocks werden alle damit definierten Resourcen geschlossen, dann brauchst du dich darum nicht selbst zu kümmern.


Und noch was ... in deinem Try Catch gibst du die Fehlermeldung nach System.out aus.
1. Wenn man schon keinen richtige Logger, will dann verwendet man für Fehler System.err
2. Ruf dann auch e.printStackTrace(System.err) auf.
Die Meldung allein ist zum Debuggen selten hilfreich, besonders wenn der Fehler weiter innen passiert.
 

mihe7

Top Contributor
Genauso, wie er es geschrieben hat:

Java:
private int anzahl;
public int getAnzahl() { return anzahl; }

EDIT: ich lese gerade, dass er "Klassenvariable" schreibt. Für eine Klassenvariable (static) sehe ich allerdings keinen Grund.
 
Zuletzt bearbeitet:

mihe7

Top Contributor
Das war mir hinterher dann auch aufgefallen :) Vermutlich sollte das einfach die Abkürzung für "Variable in der Klasse" sein.
 

FHWS

Mitglied
Hallo Leute.
Danke für eure Hinweise. Ich glaube ich stehe jedoch bei dem Thema total auf dem Schlauch... Wenn ich in der Klasse Count nun bei "public int anzahl;" einen Wert von -1 beispielsweise definiere dann überträgt er mir das auch in die GUI.
Lasse ich die -1 weg nimmt er sich die ausgezählte Variabel jedoch nicht. In der GUI steht dann eine 0. Das Problem liegt also bei der Übernahme der ausgezählten variablen "anzahl"....

Code:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

import javax.swing.JLabel;


import java.sql.DriverManager;

public class Count {

  
  
    static Connection conn;
    static Statement eintrag;
    static Statement eintrag2;
    static JLabel textPB1;
    static String ausgabe;
    Statement abfrage;
    int i;
    ResultSet res;
    private int num;
    public int anzahl;
    public int getAnzahl() { return anzahl; }
  
  
  
    Count() {
      

        try {

              Class.forName("org.mariadb.jdbc.Driver");

                    Connection con = java.sql.DriverManager.getConnection("jdbc:mariadb://fm-s012mp.fhws.de","Java","wildewalnuss");

                    Statement s = con.createStatement();

                    ResultSet res;

                    res = s.executeQuery("SELECT COUNT (*) AS anzahl FROM `lagersystem_test`.`00_hauptdatenbank` WHERE Boxinhalt > '0'" );

                    while (res.next() ) {
                      
                             
                         System.out.print(res.getString("anzahl") );
                         
                         GUI_Lager.setTextExternally(res.getString("anzahl"));
                                             
                    }
                  
                    res.close();
                    s.close();
                    con.close();

              }

              catch (Exception e) { System.out.println(""+e.getMessage());}
      
        

      
           }
  

        }
Findet jemand den Fehler ? Ich hab mittlerweile Tomaten auf den Augen...
 

Neumi5694

Top Contributor
Ich frag mal so ... an wlchem Punkt denkst du denn, dass du die Variable setzen solltest? In deinem Code machst du das nämlich nicht.
Deshalb hab ich dir den Tip mit -1 ja geschrieben, damit du genau diesen Fall erkennst: Du setzt die Variable nicht ....
 

mihe7

Top Contributor
Hier mal das Prinzip, wie es vorgeschlagen wurde. Deinen Konstruktor habe ich mal durch etwas einfaches ersetzt:

Java:
import java.awt.BorderLayout;
import javax.swing.*;

class Count {
    private int anzahl;

    public Count() {
        anzahl = (int)(Math.random() * 30);
    }

    public int getAnzahl() {
        return anzahl;
    }
}

public class Test implements Runnable {

    public void run() {
        JLabel anzahlLabel = new JLabel(" ");
        JButton button = new JButton("Abrufen");
        button.addActionListener(e -> {
            int anzahl = new Count().getAnzahl();
            anzahlLabel.setText(String.format("Es gibt %d benutzte Boxen", anzahl));
        });

        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(anzahlLabel, BorderLayout.NORTH);
        frame.add(button, BorderLayout.SOUTH);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Test());
    }

}
 

Neumi5694

Top Contributor
Lasse ich die -1 weg nimmt er sich die ausgezählte Variabel jedoch nicht. In der GUI steht dann eine 0. Das Problem liegt also bei der Übernahme der ausgezählten variablen "anzahl"....

ps: Nein, tut's nicht. 0 ist der Wert, den die Variable hat, wenn du sie nicht mit -1 initialisiert und auch sonst nirgends setzt. Die Übernahme funktioniert tadellos. Nur muss zuerst mal was drinstehen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
H Apache fop -- welche Möglichkeit gibt es um den Fortschritt anzuzeigen (Progressbar) Allgemeine Java-Themen 5
J Java Progressbar & Download Probleme Allgemeine Java-Themen 10
K Threads Thread aktualisiert Progressbar nicht Allgemeine Java-Themen 4
S Progressbar einfügen Allgemeine Java-Themen 4
D Datenbankabruff mit Progressbar anzeige Allgemeine Java-Themen 5
J MVC und ProgressBar Allgemeine Java-Themen 5
Zed ProgressBar Problem Allgemeine Java-Themen 3
P Progressbar Allgemeine Java-Themen 40
P Progressbar flackert Allgemeine Java-Themen 18
BRoll Ladestatus Ressourcen betrachten Allgemeine Java-Themen 5
S Mit Methoden kann man definieren für was <T> steht. Geht das auch irgendwie für Variablen? Allgemeine Java-Themen 12
S Kann man Variablen oder Felder definieren deren Typ zwei Interfaces ist..? Allgemeine Java-Themen 9
M Beim Öffnen Dialog Directory und Filetype definieren Allgemeine Java-Themen 2
L Eigene Dependency Injections definieren? Allgemeine Java-Themen 4
L Annotations um Gültigkeit von Attributen zu definieren? Allgemeine Java-Themen 4
E Variablen Konstanten definieren Allgemeine Java-Themen 4
U Konstante in Objekt definieren Allgemeine Java-Themen 6
T Webservice definieren und andere Webservice aufrufen Allgemeine Java-Themen 8
F Statische Methode in abstrakter Superklasse definieren Allgemeine Java-Themen 4
zilti NetBeans 6.0: neuen File Type definieren Allgemeine Java-Themen 2
Tom299 eine Konstante in Spring definieren? Allgemeine Java-Themen 4
J Objekte definieren? Allgemeine Java-Themen 2
K Compiler Fehler definieren/beeinflussen? Allgemeine Java-Themen 5
F Eigenen E-MailClient als Standart definieren Allgemeine Java-Themen 7
D ComboBox definieren Allgemeine Java-Themen 2
F Problem: mehrere Interfaces definieren equals() neu Allgemeine Java-Themen 24
TheJavaKid Taste definieren Allgemeine Java-Themen 12

Ähnliche Java Themen

Neue Themen


Oben