JProgressBar

Status
Nicht offen für weitere Antworten.
R

roli_7

Gast
Hallo allerseits.

Ich möchte während des Ladens von Daten (Dauer ca. 10 Sekunden) ein ProgressBar anzeigen. Leider bringe ich dies nicht fertig. Die Anzeige wird nicht aktualisiert. Obwohl ich einiges probiert habe und den Code inzwischen "massakriert", funktioniert es immer noch nicht.

So sieht meine ProgressBar-Klasse aus:

Code:
// imports ...

public class Progressbar extends JFrame implements Runnable
{
    /** Comment for <code>serialVersionUID</code> */
    private static final long serialVersionUID = 1L;
    private JProgressBar pBar; 
    private DataLoader dLoader;
    
    public Progressbar(DataLoader dLoader)
    {
        this.dLoader = dLoader;
        createProgressbar(); 
    }
    
    private void createProgressbar()
    {
        setLayout(null);
        
        setSize(300, 80); 
        setTitle("Laden von Daten");
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setResizable(false);
        setLocationByPlatform(true);
        
        pBar = new JProgressBar();
        pBar.setSize(new Dimension(260, 20));
        //pBar.setMaximum(dLoader.getNumberOfRows());
        pBar.setMaximum(1700000); // zum Testen
        pBar.setLocation(20, 20);
        pBar.setVisible(true);
     
        /* Dem Frame hinzufügen */
        add(pBar); 
        
        setVisible(true);
    }

    public void run()
    {
        int i = 0; 
        
//       while((i = dLoader.getCurrentRowIndex()) < dLoader.getNumberOfRows()-1)
//       {
//           pBar.setValue(i); 
//           pBar.repaint();
//           this.repaint();
//       }
       
       while (i < pBar.getMaximum())
        
       {
        pBar.setValue(++i);
        pBar.repaint();
       }
       
       dispose();
    }
}

Das ProgressBar soll kurz for dem Start der Schleife, in der die Daten geladen werden, erzeugt werden. In der Schleife wird der aktuelle Zeilenindex immer aktualisiert, da er aus dem ProgressBar-Thread abgefragt werden soll (die auskommentierte Schleife). Das Erzeugen sollte etwa wie folgt aussehen:

Code:
SwingUtilities.invokeLater(new Progressbar(referenzAufDatenLoader));

Der JFrame wird angezeigt und ich kann ihn beliebig verschieben: es wird auch während des Ladens von Daten sauber gezeichnet und man merkt absolut nichts. Einzig wird das ProgressBar nicht gezeichnet.

Ich habe es direkt in der Methode main getestet (ohne dass die Daten geladen werden). Und, in diesem Fall funktioniert es korrekt.

Ich wäre froh, wenn mir jemand helfen könnte. Denn, im Moment komme ich einfach nicht weiter.

Danke für jeden Tipp.
 
S

SlaterB

Gast
also bei mir wird nicht sauber gezeichtet,
durch das invokeLater läßt du den ATW-Thread die run-Schleife durchführen und solange der damit beschäftigt ist, wird nichts gezeichnet,

ein zweites Problem ist, dass der MaxValue der JProgressBar 1.7 Mio ist,
da wirst du mit deiner i++-Schleife nicht weit kommen, obwohl selbst das ohne Wartezeit schnell durchlaufen ist ;)

folgendes funktioniert:
Code:
public class Progressbar extends JFrame implements Runnable {
	/** Comment for <code>serialVersionUID</code> */
	private static final long serialVersionUID = 1L;
	private JProgressBar pBar;

	// private DataLoader dLoader;

	public Progressbar(
	// DataLoader dLoader
	) {
		// this.dLoader = dLoader;
		createProgressbar();
	}

	private void createProgressbar() {
		setLayout(null);

		setSize(300, 80);
		setTitle("Laden von Daten");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setResizable(false);
		setLocationByPlatform(true);

		pBar = new JProgressBar();
		pBar.setSize(new Dimension(260, 20));
		// pBar.setMaximum(dLoader.getNumberOfRows());
		pBar.setMaximum(1700000); // zum Testen
		pBar.setLocation(20, 20);
		pBar.setVisible(true);

		/* Dem Frame hinzufügen */
		add(pBar);

		setVisible(true);
	}

	public void run() {
		int i = 0;

		// while((i = dLoader.getCurrentRowIndex()) <
		// dLoader.getNumberOfRows()-1)
		// {
		// pBar.setValue(i);
		// pBar.repaint();
		// this.repaint();
		// }
		int max = pBar.getMaximum();
		System.out.println("max: " + max);
		while (i < pBar.getMaximum())

		{
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println("i: " + i);
			i += max / 100;
			pBar.setValue(i);
			pBar.repaint();
		}

		dispose();
	}

	public static void main(String[] args) {

		SwingUtilities.invokeLater(new Runnable() {

			public void run() {

				Progressbar b = new Progressbar(
				// referenzAufDatenLoader
				);

				new Thread(b).start();
			}
		});
	}
 
R

roli_7

Gast
Vielen Dank.

Ich habe es angepasst und es sieht schon viel besser aus. Jetz sehe ich auch das ProgressBar.

Habe allerdings noch ein weiteres Problem. Das ProgressBar wird erst dann angezeigt, wenn das Laden von Daten beendet ist. Dies sieht etwa wie folgt aus:
Code:
 /* ProgressBar anzeigen */
SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        Progressbar pBar = new Progressbar(null);
                    
        new Thread(pBar).start();
    }
                
});
            

for (int i = 1; i < rows; i++)
{
    // Daten werden geladen ... 

}

// Bekannt machen, dass die Daten geladen sind
System.out.println("Daten sind geladen!"); 

// Erst ab dem Punkt erscheint das Progressbar mit der Kontrollausgabe in der Console.

Ich war der Meinung, dass das Haupt-GUI korrekt funktioniert. Dazu habe ich es während des Laden von Daten verschoben, und das hat gut funktioniert. Allerdings konnte ich kein Menü öffnen!!! Danach habe ich in der Schleife nach 1000 Durchläufe ein Thread.sleep(10000) eingebaut, um zu kontrollieren, ob ich während dieser Zeit Menü im Haupt-GUI öffnen kann. Auch das hat nicht funktioniert. Sobald aber das Laden fertig ist, wird der ProgressBar angezeigt und das Haupt-GUI lässt sich problemlos bedienen. Ich vermute, dass ich das Haupt-GUI nicht richtig "gestartet" habe.

Das Haupt-GUI wird in der Klasse MainControler wie folgt gestartet:

Code:
/* ActionListener erzeugen */
final RDEActionListener aListener = new RDEActionListener(this);

/*
* MainFrame erzeugen, aber UNSICHTBAR behalten, bis LOGIN erledigt wird
*/
javax.swing.SwingUtilities.invokeLater(new Runnable()
{
    public void run()
    {
        try
        {
            mFrame = new MainFrame(aListener);
         }
        catch (Exception e)
        {
            logger.error(e.getMessage());
            JOptionPane.showMessageDialog(null, e.getMessage(), "Fehler", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }
    }
 });

 /*
 * Warten bis das Frame erzeugt wird, da für das LoginDialog benötigt
 */
 while (mFrame == null)
 {
    Thread.sleep(300);
}

Ist das in etwa korrekt, oder müsste ich auch mein Hauptframe zu einem Runnable machen? Und falls ja, was müsste n die Methode run ausgeführt werden?

Danke.
 
S

SlaterB

Gast
funktioniert mein Programm bei dir ja oder nein?
also ich sehe da von Anfang an die ProgressBar wie sie sich füllt, kann das Fenster verschieben
und minimieren und sicherlich auch ein JMenu aufrufen, wenn ich eins einbauen würde,

falls mein Programm bei dir nicht klappt, dann weiß ich auch weiter,
falls doch, dann musst du ja in deinem Programm irgendwas anders machen -> posten?
in dem angegebenen Code sehe ich jedenfalls keine Probleme

außer in einem unheilvollen Satz wie
> MainFrame erzeugen, aber UNSICHTBAR behalten, bis LOGIN erledigt wird
 
R

roli_7

Gast
Hallo SlaterB

> funktioniert mein Programm bei dir ja oder nein?

Kurz gesagt: es funktioniert.

Aber wie gesagt: erst nachdem die Schleife, in der das Laden von Daten erledigt wird, abgearbeitet ist. Danach wird das ProgressBar sauber angezeigt und aktuallisiert, wobei ich das Haupt-GUI nach Lust und Lauen verschieben und die Menüs öffnen kann. Das Problem ist allerdings nicht in deinem Lösungsvorschlag. Es ist noch irgendwo etwas in meinem Code nicht ganz sauber.

> // MainFrame erzeugen, aber UNSICHTBAR behalten, bis LOGIN erledigt wird

Ich möcthe das Haupt-GUI erst anzeigen (sichtbar machen), wenn die Anmeldung erfolgreich abgeschlossen wird. Ansonsten wird das Programm beendet und ein dispose auf dem Hautpframe aufgerufen. Also, nichts besonderes.

Vielen Dank.
 
S

SlaterB

Gast
> Aber wie gesagt: erst nachdem die Schleife, in der das Laden von Daten erledigt wird, abgearbeitet ist.

redest du da von deinem oder meinem Programm,
trotz deiner kurzen Anwort muss ich nochmal nachfragen: wird die ProgressBar aus meinem Programm bei dir sofort sauber angezeigt?

und wie zuvor:

falls mein Programm bei dir nicht klappt, dann weiß ich auch weiter,
falls doch, dann musst du ja in deinem Programm irgendwas anders machen -> posten?
 
R

roli_7

Gast
> redest du da von deinem oder meinem Programm

Ich rede von meinem Programmteil. Denn, gerade währed dem dieser Teil ausgeführt wird, soll das ProgressBar sichtbar sein. Leider erscheint es aber erst danach.

> wird die ProgressBar aus meinem Programm bei dir sofort sauber angezeigt?

Nein. Erst nach dem Daten geladen sind.
 
S

SlaterB

Gast
trali trala
SlaterB hat gesagt.:
dann musst du ja in deinem Programm irgendwas anders machen -> posten?

oder willst du die nächsten Tage nur ab und zu mal mitteilen, dass dein Programm nicht geht?
 
R

roli_7

Gast
> trali trala :lol:

Probieren wir es.

Die Main-Klasse:
Code:
package de;

import de.controler.MainControler;

public class Main
{
    public static void main(String[] args)
    {
       new MainControler().execute();     
    }
}

Die MainControler-Klasse:
Code:
package de.controler;

import java.sql.SQLException;

import javax.swing.JOptionPane;

import org.apache.log4j.Logger;

import com.sun.org.apache.xerces.internal.impl.PropertyManager;

import de.business.DataLoader;
import de.gui.MainFrame;
import de.gui.event.RDEActionListener;


public class MainControler
{
    private static Logger logger = Logger.getLogger(MainControler.class);

    private MainFrame mFrame = null;

    /**
     * Steuert die Ausführung der Anwendung.
     */
    public void execute()
    {
        boolean loginOk = false;

        try
        {
            /* Properties setzen */
            PropertyManager.setProperties();

            /* ActionListener erzeugen */
            final RDEActionListener aListener = new RDEActionListener(this);

            /*
             * MainFrame erzeugen, aber UNSICHTBAR behalten, bis LOGIN erledigt
             * wird
             */
            javax.swing.SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    try
                    {
                        mFrame = new MainFrame(aListener);
                    }
                    catch (Exception e)
                    {
                        logger.error(e.getMessage());
                        JOptionPane.showMessageDialog(null, e.getMessage(),
                                "Fehler", JOptionPane.ERROR_MESSAGE);
                        System.exit(0);
                    }
                }
            });

            /*
             * Warten bis das Frame erzeugt wird, da für das LoginDialog
             * benötigt
             */
            while (mFrame == null)
            {
                Thread.sleep(300);
            }

            /* Anmeldung verlangen */
            loginOk = login(mFrame);

            /* Je nach Anmeldungsergebnis, ... */
            if (loginOk)
            {
                /*
                 * Falls die Anmeldung korrekt war, das MainFrame sichtbar
                 * machen
                 */
                mFrame.setVisible(true);
            }
            else
            {
                /* Ressourcen frei geben */
                mFrame.dispose();
                /* Die Ausführung beenden */
                System.exit(0);
            }

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

            JOptionPane
                    .showMessageDialog(
                            null,
                            "Fehler in der Ausführung der Applikation. Wenden Sie sich bitte an den Administrator.",
                            "Fehler", JOptionPane.ERROR_MESSAGE);
        }

    }

    /**
     * Laden von Daten veranlassen.
     */
    public void loadData()
    {
        /* Datei mit Daten abfragen */
        String inputFileName = getInputFileName();

        /* Anzahl Zeilen, die nicht eingelesen werden konnten */
        int anzahl = 0;

        if (inputFileName != null)
        {

            /* Die Telefonnummer abfragen */
            String telNr = getPhoneNumber();

            if (telNr != null)
            {
                /* Daten laden */
                try
                {
                    /* Ein DataLoader-Objekt erzeugen */
                    DataLoader dLoader = new DataLoader(inputFileName, telNr, mFrame);
                    /* Daten laden */
                    anzahl = dLoader.loadData();
                    
                    /* Reportgenerierung enablen */
                    mFrame.getMItemGenerateReport().setEnabled(true);
                    
                    /* Db runterfahren */
                    DbHandler.getInstance().shutdown();

                    /*
                     * Falls es fehlerhafte Zeilen gegeben hat, die nicht
                     * eingelesen werden konnten, ...
                     */
                    if (anzahl > 0)
                    {
                        String msg = null;

                        if (anzahl == 1)
                        {
                            msg = "Ein Datensatz konnte nicht korrekt eingelesen werden.";
                        }
                        else
                        {
                            msg = anzahl
                                    + " Datensätze konnten nicht eingelesen werden.";
                        }

                        JOptionPane.showMessageDialog(null, msg, "Fehler",
                                JOptionPane.INFORMATION_MESSAGE);
                    }

                    JOptionPane.showMessageDialog(null,
                            "Daten erfolgreich geladen.", "Daten geladen",
                            JOptionPane.INFORMATION_MESSAGE);
                    
                }
                catch (SQLException e)
                {
                    logger.error(e.getMessage());
                    JOptionPane.showMessageDialog(null,
                            "Fehler beim Laden von Daten.", "Fehler",
                            JOptionPane.ERROR_MESSAGE);
                }
                catch (Exception e)
                {
                    logger.error(e.getMessage());
                    JOptionPane.showMessageDialog(null,
                            "Fehler beim Laden von Daten.", "Fehler",
                            JOptionPane.ERROR_MESSAGE);
                }
            }
        }
        else
        {
            JOptionPane
                    .showMessageDialog(
                            null,
                            "Die von Ihnen angegebene Datei existiert nicht oder ist korrupt.",
                            "Fehler", JOptionPane.ERROR_MESSAGE);
        }

    }

    /**
     * Beendet die Ausführung.
     */
    public void exit()
    {
        mFrame.dispose();
        System.exit(0);
    }
}

Die DataLoader-Klasse:

Code:
package de.business;

import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;

import org.apache.log4j.Logger;

import de.db.DbHandler;
import de.gui.MainFrame;
import de.gui.Progressbar;
import de.model.Communication;
import de.reader.DataReader;
import de.util.Util;



public class DataLoader
{
    private String fileName;
    private String telefon;
    
    private MainFrame mFrame;

    private static Logger logger = Logger.getLogger(DataLoader.class);

    /*
     * Anzahl Communication-Objekte, die in der Liste abgelegt werden, bevor sie
     * in die Datenbanke geschrieben werden
     */
    private final int SIZE = 1000;

    /**
     * @param fileName String
     * @param telefon String
     * @param mFrame MainFrame
     */
    public DataLoader(String fileName, String telefon, MainFrame mFrame)
    {
        this.mFrame = mFrame;
        this.fileName = fileName;
        this.telefon = telefon;
    }
    

    /**
     * Steuert das Laden von Daten aus der Excel-Datei in die Datenbank.
     * @return invalidRowCnt int Die Anzahl der Zeilen (Datenrecords), die
     *         korrupt sind und nicht geparst werden konnten.
     * @throws SQLException
     * @throws Exception
     */
    public int loadData() throws SQLException, Exception
    {
        /*
         * Anzahl Zeilen (Datenrecords), die nicht "valid" sind und nicht
         * korrekt geparst werden können
         */
        int invalidRowCnt = 0;

        DbHandler dbHandler = null;

        try
        {
            // Eine DbHandler-Instanz holen
            dbHandler = DbHandler.getInstance();

            // Vorhandene Tabellen löschen
            dbHandler.deleteDbContent();

            /* Tabellen neu anlegen */
            dbHandler.createTables();

            /* Den DataReader erzeugen */
            DataReader dataReader = new DataReader(fileName);

            /* Anzahl Zeilen abfragen */
            int rows = dataReader.getRows();



            /*
             * Zeile für Zeile werden aus der Excel-Datei ausgelesen, in das
             * Communication-Objekt geschrieben und anschliessend in die Liste
             * 'lstCom' abgelegt. Wenn die 'lstCom' SIZE-Communication-Objekte
             * enthält, wird Sie an die entsprechende Methode zwecks Schreibens
             * in die Datenbank übergeben.
             */

            /* Liste, in der die Communication-Objekte verwaltet werden */
            ArrayList<Communication> lstCom = new ArrayList<Communication>();
            /* Zeile aus der Excel-Datei */
            ArrayList<String> row = null;
            /* Temporäre Objektvariable */
            Communication c = null;
            
            /* ProgressBar anzeigen */
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    Progressbar pBar = new Progressbar(null);
                    
                    new Thread(pBar).start();
                }
                
            });
            

            for (int i = 1; i < rows; i++)
            {
                /* Eine Zeile aus der Excel-Datei holen */
                row = dataReader.getRowAt(i);
                /* Daten aus der Zeile in das Connection-Objekt ablegen */
                c = Util.parseConnection(row, telefon);

                if (c != null)
                {
                    /* Das Communication-Objekt in die Liste 'lstCom' ablegen */
                    lstCom.add(c);

                    /*
                     * Falls die Liste die SIZE-Grösse erreicht habe, wird das
                     * Schreiben in die Datenbank veranlasst
                     */
                    if (lstCom.size() % SIZE == 0)
                    {
                        /* FOR DEBUG */
                        // System.out.println("NOW!");
                        // Thread.sleep(10000);
                        
                        /* Daten in die Datenbank schreiben */
                        dbHandler.addToTableCom(lstCom);

                        /* Liste leeren */
                        lstCom.clear();
                    }
                }
                else
                {
                    logger
                            .error("\n\t### Fehler beim Parsen des Timestamps!\n\t### Fehlerhafte Zeile: "
                                    + (i + 1) + "\n");
                    invalidRowCnt++;
                }
            }

            System.out.println("FERTIG");
            
            /*
             * Den Inhalt der Liste (evtl. weniger als SIZE) in die Datenbank
             * schreiben
             */
            dbHandler.addToTableCom(lstCom);
        }
        catch (ClassNotFoundException e)
        {
            logger.error(e.getMessage());
            throw new SQLException("Fehler beim Laden von Daten.");
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
            throw new SQLException("Fehler beim Laden von Daten.");
        }
        catch (Exception e)
        {
            logger.error(e.getMessage());
            throw new Exception("Fehler beim Laden von Daten.");
        }

        return invalidRowCnt;
    }
}

Die MainFrame-Klasse:
Code:
package de.gui;

import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;

import de.gui.event.RDEActionListener;


public class MainFrame extends JFrame
{
    private static final long serialVersionUID = 1L;
    private JMenuBar menuBar = null;
    private JMenu fileMenu = null;
    private JMenu dataMenu = null;
    private JMenu optionsMenu = null;
    private JMenu helpMenu = null;
    
    private JMenuItem mItemGenerateReport = null; 

    public MainFrame(RDEActionListener aListener) throws Exception
    {
        /* Titel setzen */
        super("Daten Explorer");

        /* Schliesen des Frames */
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        /* Position definieren */
        setLocationByPlatform(true);

        /* Grösse definieren */
        setSize(new Dimension(600, 300));
        /* Grösse nicht änderbar */
        setResizable(false);

        /* Menues erzeugen */
        setMenues();

        /* Datei */
        setMenueItem(fileMenu, "Beenden", 'B', 'E', "EXIT", aListener,
                "xxx");

        /* Daten */
        setMenueItem(dataMenu, "Daten laden", 't', 'L', "LOAD_DATA", aListener,
                "Starte das Laden der Daten.");
        mItemGenerateReport =  setMenueItem(dataMenu, "Report generieren", 'G', 'G',
                "GENERATE_REPORT", aListener,
                "xxx");
        
        /* Einstellunge */
        setMenueItem(
                optionsMenu,
                "Benutzerprofil",
                'P',
                'P',
                "PROFIL",
                aListener,
                "xxx");
        setMenueItem(
                optionsMenu,
                "Reporteinstellungen",
                'R',
                'R',
                "REPORT_CONFIGS",
                aListener,
                "xxx");


        /* UNSICHTBAR machen (da die Anmeldung erst erfolgen muss) */
        setVisible(false);
    }

    private void setMenues()
    {
        /* MenuBar erzeugen */
        menuBar = new JMenuBar();

        /* Menüs erzeugen */
        fileMenu = new JMenu("Datei");
        fileMenu.setMnemonic('D');

        dataMenu = new JMenu("Daten");
        dataMenu.setMnemonic('T');

        optionsMenu = new JMenu("Optionen");
        optionsMenu.setMnemonic('O');

        helpMenu = new JMenu("Hilfe");
        helpMenu.setMnemonic('H');

        /* Menüs dem menuBar hinzufügen */
        menuBar.add(fileMenu);
        menuBar.add(dataMenu);
        menuBar.add(optionsMenu);
        menuBar.add(helpMenu);

        /* Menubar dem JFrame hinzufügen */
        setJMenuBar(menuBar);
    }

    private JMenuItem setMenueItem(JMenu menue, String label, char mnemonic,
            char taste, String actionCommand, ActionListener aListener,
            String toolTip)
    {
        JMenuItem mItem = null;

        mItem = new JMenuItem(label);
        mItem.setAccelerator(KeyStroke
                .getKeyStroke(taste, InputEvent.CTRL_MASK));
        mItem.setMnemonic(mnemonic);
        mItem.setActionCommand(actionCommand);
        mItem.addActionListener(aListener);
        mItem.setToolTipText(toolTip);
        menue.add(mItem);

        return mItem;
    }
}

Ich habe probiert, das für das Verständnis benötigte mitzugeben. Das Anzeigen des ProgressBars wird in der Methode DataLoader.loadData gestartet (ab Zeile 99). Ab Zeile 111 wird das Laden von Daten gestartet. Das Erzeugen des Main-GUIs ist in der Methode MainControler.execute (ab Zeile 42) zu finden.
 
G

Guest

Gast
ist DataReader eine klasse aus einer bibliothek, oder von dir programmiert? funktioniert sie richtig?
 
S

SlaterB

Gast
also ich kann mit dem Code leider nix anfangen,
alles nur rot angestrichen und unnötig lang

---------

RDEActionListener aListener = new RDEActionListener(this);

unbekannte Klasse

----------

loadData()
kann man sicherlich zu einem einfachen Thread.sleep() oder einer Schleife von Thread.sleep() zusammenkürzen,
ohne irgendwelche DB-Verbindungen, die dürften mit dem Problem nix zu tun haben

--------

wieso
> mFrame.getMItemGenerateReport().setEnabled(true);
aber keine entsprechende Operation in MainFrame?

-----

wieso

catch (ClassNotFoundException e)
{
logger.error(e.getMessage());
throw new SQLException("Fehler beim Laden von Daten.");
}
catch (SQLException e)
{
logger.error(e.getMessage());
throw new SQLException("Fehler beim Laden von Daten.");
}
catch (Exception e)
{
logger.error(e.getMessage());
throw new Exception("Fehler beim Laden von Daten.");
}

?
das kann man doch zu


catch (Exception e)
{
logger.error(e.getMessage());
throw new SQLException("Fehler beim Laden von Daten.");
}

kürzen


---------


ist

/* Datei */
setMenueItem(fileMenu, "Beenden", 'B', 'E', "EXIT", aListener, "xxx");

/* Daten */
setMenueItem(dataMenu, "Daten laden", 't', 'L', "LOAD_DATA", aListener, "Starte das Laden der Daten.");
mItemGenerateReport = setMenueItem(dataMenu, "Report generieren", 'G', 'G', "GENERATE_REPORT", aListener, "xxx");

/* Einstellunge */
setMenueItem(optionsMenu, "Benutzerprofil", 'P', 'P', "PROFIL", aListener, "xxx");
setMenueItem(optionsMenu, "Reporteinstellungen", 'R', 'R', "REPORT_CONFIGS", aListener, "xxx");


wirklich zur Lösung des Problems nötig?
 
R

roli_7

Gast
Sorry, wir haben uns offenbar nicht verstanden.

O.K. Ich habe jetzt das Program auf ein Minimum reduziert und alles, was "unnötig" ist, entfernt. Der Rest ist allerdings ausführbar. Das Laden von Daten wurde durch eine Schleife, die etwa 10 Sekunden dauert, ersetzt. Das Problem ist weiterhin vorhanden.

Nachfolgend werden die Klassen angegeben, die "überlegt" haben.

Klasse Main:

Code:
package rd;

import rd.controler.MainControler;

public class Main
{
    public static void main(String[] args)
    {
       new MainControler().execute();     
    }
}

Klasse MainControler:
Code:
package rd.controler;

import rd.business.DataLoader;
import rd.gui.MainFrame;
import rd.gui.event.RDEActionListener;

public class MainControler
{
    private MainFrame mFrame = null;

    /**
     * Steuert die Ausführung der Anwendung.
     */
    public void execute()
    {
        try
        {
            /* ActionListener erzeugen */
            final RDEActionListener aListener = new RDEActionListener(this);

            /*
             * MainFrame erzeugen, aber UNSICHTBAR behalten, bis LOGIN erledigt
             * wird
             */
            javax.swing.SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    try
                    {
                        mFrame = new MainFrame(aListener);
                    }
                    catch (Exception e)
                    {
                        System.exit(0);
                    }
                }
            });
        }
        catch (Exception e)
        {
        }
    }

    public void loadData()
    {
        /* Die Telefonnummer */
        String telNr = "2222222";

        if (telNr != null)
        {
            /* Daten laden */
            try
            {
                /* Ein DataLoader-Objekt erzeugen */
                DataLoader dLoader = new DataLoader("xxx", telNr, mFrame);
                /* Daten laden */
                dLoader.loadData();
            }
            catch (Exception e)
            {
                // xxx
            }
        }
    }

    /**
     * Beendet die Ausführung.
     */
    public void exit()
    {
        mFrame.dispose();
        System.exit(0);
    }
}

Klasse DataLoader:

Code:
package rd.business;

import java.sql.SQLException;

import javax.swing.SwingUtilities;

import rd.gui.MainFrame;
import rd.gui.Progressbar;

public class DataLoader
{

    public DataLoader(String fileName, String telefon, MainFrame mFrame)
    {
        // ...
    }

    public int loadData() throws SQLException, Exception
    {
        /* ProgressBar anzeigen */
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                Progressbar pBar = new Progressbar(null);

                new Thread(pBar).start();
            }

        });

        long time = new java.util.Date().getTime();

        long endTime = time + 10000;

        while (new java.util.Date().getTime() < endTime)
        {
            ;
        }

        return -1;
    }
}

Klasse MainFrame:
Code:
package rd.gui;

import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;

import rd.gui.event.RDEActionListener;

public class MainFrame extends JFrame
{
    private static final long serialVersionUID = 1L;
    private JMenuBar menuBar = null;
    private JMenu fileMenu = null;
    private JMenu dataMenu = null;
   
    public MainFrame(RDEActionListener aListener) throws Exception
    {
        /* Titel setzen */
        super("Daten Explorer");

        /* Schliesen des Frames */
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        /* Position definieren */
        setLocationByPlatform(true);

        /* Grösse definieren */
        setSize(new Dimension(600, 300));
        /* Grösse nicht änderbar */
        setResizable(false);

        /* Menues erzeugen */
        setMenues();

        /* Datei */
        setMenueItem(fileMenu, "Beenden", 'B', 'E', "EXIT", aListener,
                "Beendet die Ausführung der Applikation.");

        /* Daten */
        setMenueItem(dataMenu, "Daten laden", 't', 'L', "LOAD_DATA", aListener,
                "Starte das Laden der Daten.");
        
        this.setVisible(true);
    }

    private void setMenues()
    {
        /* MenuBar erzeugen */
        menuBar = new JMenuBar();

        /* Menüs erzeugen */
        fileMenu = new JMenu("Datei");
        fileMenu.setMnemonic('D');

        dataMenu = new JMenu("Daten");
        dataMenu.setMnemonic('T');

        /* Menüs dem menuBar hinzufügen */
        menuBar.add(fileMenu);
        menuBar.add(dataMenu);

        /* Menubar dem JFrame hinzufügen */
        setJMenuBar(menuBar);
    }

    private JMenuItem setMenueItem(JMenu menue, String label, char mnemonic,
            char taste, String actionCommand, ActionListener aListener,
            String toolTip)
    {
        JMenuItem mItem = null;

        mItem = new JMenuItem(label);
        mItem.setAccelerator(KeyStroke
                .getKeyStroke(taste, InputEvent.CTRL_MASK));
        mItem.setMnemonic(mnemonic);
        mItem.setActionCommand(actionCommand);
        mItem.addActionListener(aListener);
        mItem.setToolTipText(toolTip);
        menue.add(mItem);

        return mItem;
    }
}

Klasse ProgressBar:
Code:
package rd.gui;

import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JProgressBar;

import rd.business.DataLoader;

public class Progressbar extends JFrame implements Runnable
{
    /** Comment for <code>serialVersionUID</code> */
    private static final long serialVersionUID = 1L;
    private JProgressBar pBar;
    public Progressbar(DataLoader dLoader)
    {
        createProgressbar();
    }

    private void createProgressbar()
    {
        setLayout(null);

        setSize(300, 80);
        setTitle("Laden von Daten");
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setResizable(false);
        setLocationByPlatform(true);

        pBar = new JProgressBar();
        pBar.setSize(new Dimension(260, 20));
        pBar.setMaximum(17000000); // zum Testen
        pBar.setLocation(20, 20);
        pBar.setVisible(true);

        /* Dem Frame hinzufügen */
        add(pBar);

        setVisible(true);
    }

    /**
     * @return pBar JProgressBar
     */
    public JProgressBar getPBar()
    {
        return pBar;
    }

    public void run()
    {
        int i = 0;

        int max = pBar.getMaximum();
        System.out.println("max: " + max);

        while (i < max)
        {
            try
            {

                Thread.sleep(100);

            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            
            System.out.println("i: " + i);
            
            i += max / 1000;
            
            pBar.setValue(i);
            pBar.repaint();
        }
        
        dispose();
    }
}

Und schlussendliche die ListenerKlasse:
Code:
package rd.gui.event;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import rd.controler.MainControler;

public class RDEActionListener implements ActionListener
{
    private MainControler mc = null;

    public RDEActionListener (MainControler mController)
    {
        this.mc = mController;
    }

    public void actionPerformed(ActionEvent event)
    {
        if (event.getActionCommand().equals("EXIT"))
        {
            mc.exit();       
        }
        else if (event.getActionCommand().equals("LOAD_DATA"))
        {
            System.out.println("Daten werde geladen!");
            mc.loadData();
        }
        else
        {
            System.out.println("Es wird was anderes gemacht ... ");
        }
    }
}

Ich hoffe, dass jetzt keine Fehlermeldungen erscheinen werden.
 
R

roli_7

Gast
Anonymous hat gesagt.:
ist DataReader eine klasse aus einer bibliothek, oder von dir programmiert? funktioniert sie richtig?

Es ist eine Klasse, die von mir erstellt wurde. Da die Daten korrekt geladen werden, gehe ich davon aus, dass sie auch korrekt ist.
 
S

SlaterB

Gast
loadData() wird in einer actionPerformed aufgerufen,
10 Sec. lang ist also die GUI blockiert und es wird nichts gezeichnet,

dass nebenbei 0, 1 oder 100 Threads korrekt nebenläufig arbeiten, spielt nur eine geringe Rolle,
wenn der AWT-Thread durch nur eine Aufgabe 10 Sec. blockiert ist, dann ist er eben blockiert


die Arbeit von loadData() muss in einen Thread ausgeführt werden,
ob die JProgressbar in einem zweiten Thread oder zusammen bearbeitet wird ist Geschmackssache,
eher eine Trennung von GUI-Code/ Arbeits-Code, mit Nebenläufigkeit zur GUI hat das dann weniger zu tun wenn der gesamte loadData()-Aufruf nebenläufig ist,

das Updaten der JProgressbar sollte vom Stand der Arbeit von loadData() abhängen,
aber das hast du vielleicht auch schon für später geplant
 
R

roli_7

Gast
Alles klar.

Ich habe die benötigten Änderungen vorgenommen und es funktioniert einwandfrei.

Herzlichen Dank für deine Hilfe.
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben