-
02-06-2007, 20:31 #1Member
- Registered
- 16/09/02
- Location
- Antwerpen
- Posts
- 2,211
- iTrader
- 6 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/2
[PROG][JAVA] Jframe met progressbar die werkt met aparte thread
Om mijn vraag wat te verduidelijken:
Voor een project moeten wij csv inlezen en deze in de database zetten, omdat dit nogal lang kan duren als de database op ne remote server staat zouden wij graag een Jframe maken met een progressbar in die werkt via een Thread (als we dit ni via een thread doen zal de JFrame pas tevoorschijn komen als alles al gdn is).
Dit is wat ik nu heb:
De Thread klasse
De Jframe die via de thread wordt opgeroepenCode://* * CsvCheckDoneThread.java * * Created on 2 juni 2007, 18:12 * * To change this template, choose Tools | Template Manager * and open the template in the editor. */ package Data; import View.CsvProgress; import java.awt.*; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JProgressBar; /** * * @author Welles */ public class CsvCheckDoneThread implements Runnable { CsvProgress progress=new CsvProgress(); boolean ok=true; /** Creates a new instance of CsvCheckDoneThread */ public CsvCheckDoneThread(){ } public void run() { progress.setVisible(true); } public void stopthread(){ progress.dispose(); ok=false; } public void setValue(int value){ progress.setValue(value); } }
De functie waarin de Thread gestart wordtCode:/* * CsvProgress.java * * Created on 2 juni 2007, 18:35 */ package View; import javax.swing.*; import java.awt.*; /** * * @author Welles */ public class CsvProgress extends JFrame { /** Creates new form CsvProgress */ public CsvProgress() { initComponents(); //centerscreen(); this.prgbar.setValue(0); } private void centerscreen(){ Dimension dim = getToolkit().getScreenSize(); Rectangle abounds = getBounds(); setLocation((dim.width - abounds.width) / 2,(dim.height - abounds.height) / 2); } public void setValue(int value){ this.prgbar.setValue(this.prgbar.getValue()+value); } // <editor-fold defaultstate="collapsed" desc=" Generated Code "> private void initComponents() { jPanel1 = new javax.swing.JPanel(); prgbar = new javax.swing.JProgressBar(); jLabel1 = new javax.swing.JLabel(); jPanel2 = new javax.swing.JPanel(); jLabel2 = new javax.swing.JLabel(); setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setAlwaysOnTop(true); setBackground(new java.awt.Color(214, 205, 244)); setResizable(false); prgbar.setStringPainted(true); jLabel1.setFont(new java.awt.Font("Calibri", 0, 14)); jLabel1.setForeground(new java.awt.Color(0, 0, 153)); jLabel1.setText("<html>De csv's worden geladen.<br><p align=\"center\">Even geduld aub</p></html>"); jPanel2.setBackground(new java.awt.Color(67, 67, 201)); jLabel2.setFont(new java.awt.Font("Calibri", 0, 48)); jLabel2.setForeground(new java.awt.Color(255, 255, 255)); jLabel2.setText("<html>D<br>C<br>I</html>"); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addGap(29, 29, 29) .addComponent(jLabel2) .addContainerGap(37, Short.MAX_VALUE)) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 179, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(23, Short.MAX_VALUE)) ); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(27, 27, 27) .addComponent(prgbar, javax.swing.GroupLayout.PREFERRED_SIZE, 242, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(jPanel1Layout.createSequentialGroup() .addGap(80, 80, 80) .addComponent(jLabel1))) .addGap(34, 34, 34)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() .addContainerGap(65, Short.MAX_VALUE) .addComponent(jLabel1) .addGap(18, 18, 18) .addComponent(prgbar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(77, 77, 77)) .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); pack(); }// </editor-fold> /** * @param args the command line arguments */ // Variables declaration - do not modify private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JProgressBar prgbar; // End of variables declaration }
Dit blijkt dus niet te werken, want hij laat de JFrame enkel zien als alles gedaan isCode:public void InitializeCsv(String path) throws SQLException, IOException{ csvcheckclass=new CsvCheckDoneThread(); Thread cvsth = new Thread(csvcheckclass); try{ cvsth.start(); Csv c= new Csv(game, wedstrijd, speeldag, speler, team, club, reeks, bc,csvcheckclass); c.LeesCsv(path); kalender k= new kalender(14,wedstrijd,team, club, bc); k.create(); csvcheckclass.stopthread(); } catch (SQLException e){ csvcheckclass.stopthread(); throw new SQLException(); } }
.
Iemand een idee hoe ik dit kan oplossen?
mvg
Yannick Wellensno votes
-
-
03-06-2007, 00:47 #2Member
- Registered
- 16/09/02
- Location
- Antwerpen
- Posts
- 2,211
- iTrader
- 6 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/2
Niemand
no votes
-
03-06-2007, 12:48 #3Member
- Registered
- 22/10/02
- Location
- Brugge & Gent
- Posts
- 657
- iTrader
- 0
- Mentioned
- 0 Post(s)
- Reputation
- 0/1
public void run() {
progress.setVisible(true);
}
Een thread wordt beïndigd als de run methode ten einde is. Dus wat hier gebeurt als je de thread start, is dat er een nieuwe thread gestart wordt, deze thread voert setVisible van uw progress JFrame uit in de thread wordt beïndigd.
// edit: Is het echt de bedoeling dat de progress bar de hoeveelheid verkregen data van het totaal toont? Ik zie niet echt een manier hoe je dit kunt meten (en dus de juiste waarde door de progressbar laten tonen).no votes
-
03-06-2007, 15:05 #4Member
- Registered
- 16/09/02
- Location
- Antwerpen
- Posts
- 2,211
- iTrader
- 6 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/2
Ja, da meten is gelukt
. Ik zie gwn hoeveel functies em moet uitvoeren, dan doe ik 100/aantal functies, zo weet ik hoeveel em moet updaten na elke functie die gdn is.
Is er dus ook een oplossing voor dit probleem, zou ik op 1 of andere manier ervoor kunnen zorgen dat de thread blijft bestaan tot de kader moet sluiten?
Ik denk omdat Swing sowieso al een eigen thread gebruik, de thread die ik aangeef niet wordt gebruikt om mijn Jframe te tekenen, hierdoor moet ik dus wachten totdat de csv'z zijn ingelezen alvorens het scherm te krijgen.
mvgLast edited by yannick; 03-06-2007 at 15:47.
no votes
-
04-06-2007, 00:15 #5Member
- Registered
- 16/09/02
- Location
- Antwerpen
- Posts
- 2,211
- iTrader
- 6 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/2
Weet niemand hier een antwoord op? Want ik zou dit toch nog graag in mijn project krijgen

mvgno votes
-
04-06-2007, 16:06 #6Member
- Registered
- 17/07/02
- Location
- PSPACE
- Posts
- 4,603
- iTrader
- 14 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/18
Je mag niet zomaar Swing-functies oproepen vanuit andere threads, dus ook niet zomaar rechtstreeks methodes van een frame aanroepen.
Hier is meer info:
http://java.sun.com/products/jfc/tsc.../threads1.html
Het keyword "EventDispatcherThread" of "EventDispatchThread" (niet meer zeker van de naam) kan ook al wat helpen bij je zoektocht.
Uw vraag over de "stopthread()" (geen goede code voor thread-safety redenen trouwens): ja daar is een goede manier voor.
Maak dan dat je frame sluitknop enkel je frame invisible maakt en dan stopt de thread automatisch als deze gesloten wordt en smijt de thread je frame weg (desnoods zet je de dispose in de frame-sluitknop, maar ik vrees voor synchronisatieproblemen dan: wat het effect van visible op een disposed frame oproepen is weet ik namelijk niet).Code:public run () { SwingUtilities.invokeLater(new Runnable { run () { frame.setVisible(true); } }); while (frame.isVisible()) { } frame.dispose(); }
Doe alleszins die "stopthread()" weg, dat is niet de goede manier om een thread te stoppen (een voorwaardelijke whilelus wordt meestal gebruikt).Last edited by QplQyer; 04-06-2007 at 16:16.
Only art and science can and try to change the world, therefore paying millions to useless sportsmen is sheer idiocy.
The man, the legend: Dijkstrano votes
-
04-06-2007, 18:57 #7Member
- Registered
- 16/09/02
- Location
- Antwerpen
- Posts
- 2,211
- iTrader
- 6 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/2
Ja sry, die stopthread() ben ik vergeten te veranderen hier. Ik doe het normaal altijd met een while lus.
In stopthread had moeten staan: killme=true; en dan had ik het zo met een while gedaan: while(!killme).
Maar omdat ik nog nooit een thread had gebruikt voor een Jframe op te roepen deed ik het hier anders
Kzal allesinds da stukske code is proberen.
Heel hard bedankt voor de moeite
!!
*EDIT*
Da stukske code help me eig nog altijd niet verder
. Want hij laat de gui pas zien als alles ingelezen is. Ik moet dus ervoor zorgen dat deze Jframe TIJDENS het inlezen getoond wordt en de progressbar wordt geupdate 
mvgLast edited by yannick; 04-06-2007 at 19:10.
no votes
-
04-06-2007, 21:11 #8Member
- Registered
- 17/07/02
- Location
- PSPACE
- Posts
- 4,603
- iTrader
- 14 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/18
Ja, ik had je code eigenlijk nog niet zo goed bekeken en dus over het hoofd gezien dat je niet alles laadt in die aparte thread, noch de status controleert in die aparte thread.
Je probleem is dat je niet in de thread gewoon een JFrame moet tonen, maar de update-methode voor de progressbar in je thread moet steken (en eventueel de laadcode). Als je immers die JFrame nu in die thread laat tonen (door invokeLater() op te roepen), heb je het probleem van het wachten op het laden niet omzeild omdat de DispatchThread nog altijd blokkeert tijdens dat laden (en pas na het laden die invokeLater() eindelijk zal uitvoeren.
Dus iets zoals dit:
Zoiets zou je dus moeten gebruiken (behoudens de klassenaam-fouten, de +5 enzo natuurlijk. Hoe je de status opvraagt ben ik nu wel niet meer zeker. Ik denk dat je wel get-methoden kunt opvragen vanuit een aparte thread, maar niet het tekenen kunt beïnvloeden, maar dat ben ik dus hoegenaamd niet meer zeker.Code:public void run () { while (true) { // Check status van het laden en de eventueel de laadcode zelf SwingUtilities.invokeLater(new Runnable () { progressbar.setValue(progressbar.getValue()+5)) } }
Kijk ook eens op de link die ik gaf, die heeft een voorbeeld van hoe je een laadscherm moet aanpakken.Last edited by QplQyer; 04-06-2007 at 21:17.
Only art and science can and try to change the world, therefore paying millions to useless sportsmen is sheer idiocy.
The man, the legend: Dijkstrano votes
-
04-06-2007, 22:27 #9Member
- Registered
- 16/09/02
- Location
- Antwerpen
- Posts
- 2,211
- iTrader
- 6 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/2
Mja ben aant zoeken, maar nog niet echt gevonden (kben ook bezig met java server faces, exaam morge, het java project moet trouwens morge ook af zijn
. Tis enkel dit stuk dat nog niet werkte, als ik iets in menne kop haal moet ik het der ook in krijgen, eigen aan het beesje
.
Bedankt voor de hulp allesinds, kheb weer wat bijgeleerd
*edit*
pff never mind. Zelfs met al uw hulp krijg ik deze kader ni getoond. Kzalt maar laten zo want ik werk wrs ook al ff op uw zenuwen: "Waarom kan die lompe **** da nu ni vinden
"
For the record
Dit is de code, het is waarschijnlijk verkeerd, maja bonCode:public void run() { while (ok) { // Check status van het laden en de eventueel de laadcode zelf SwingUtilities.invokeLater(new Runnable (){ public void run() { CsvProgress progress=new CsvProgress(); progress.setVisible(true); } }); } }
.
Deze code ook geprobeerd omdat ik het nogal raar vond da da allemaal in een while lus staat (hij doet er dan altijd ne invoke later bij, denk ik):
*EDIT2*Code:public void run() { // Check status van het laden en de eventueel de laadcode zelf SwingUtilities.invokeLater(new Runnable (){ public void run() { CsvProgress progress=new CsvProgress(); progress.setVisible(true); } }); }
ok ik heb wat liggen testen door gwn een a te laten afprinten binnen de invokelater. Wat blijkt, dit doet em ook pas wanneer alles gdn is-> Hij gebruikt gwn niets van thread of invokelater.
Als ik dit probeer in de klasse zelf (dus waar ik normaal de thread aanroep), doet hij ook net hetzelfde.
Heb het ff getest met dit:
Zo een raar probleem pfffCode:public void InitializeCsv(String path) throws IOException, SQLException{ /*CsvCheckDoneThread csvdoneth = new CsvCheckDoneThread(); Thread th = new Thread(csvdoneth); th.start();*/ SwingUtilities.invokeLater(new Runnable (){ public void run() { System.out.println("a"); } }); try { Thread.sleep(3000); } catch (InterruptedException ex) { ex.printStackTrace(); } /*Csv c= new Csv(game, wedstrijd, speeldag, speler, team, club, reeks, bc); c.LeesCsv(path); kalender k= new kalender(14,wedstrijd,team, club, bc); k.create(); //csvdoneth.stopThread();*/ }
mvgLast edited by yannick; 04-06-2007 at 23:00.
no votes
-
04-06-2007, 23:18 #10Member
- Registered
- 17/07/02
- Location
- PSPACE
- Posts
- 4,603
- iTrader
- 14 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/18
Een vraagje: zit de laadcode eigenlijk in een aparte Thread?
Indien nee, dan zit daar (een deel van) het probleem: Swing zal altijd blokkeren totdat het laden gedaan is. Het JFrame zal dus pas tevoorschijn komen als Swing klaar is om het te tonen en dat is na de blokkering van het laden.
Indien ja: ok goed.
---
Oplossing voor alles:
- Steek de laad-code in een aparte thread.
- Geef aan deze thread een referentie naar een JProgressBar mee
- In de code die het laden start (niet in de thread-code!) maak je eerst een JFrame aan met een progressbar en je zet die op visible.
- Je maakt een nieuw laad-thread object aan en je geeft de referentie naar de JProgressBar op het pas aangemaakte frame mee.
- In de laad-thread update je telkens wanneer je klaar bent met iets in te laden ofzo de JProgressBar zijn waarde door de dispatchLater () op te roepen met een Runnable die op die progressbar gewoon setValue uitvoert met de juiste waarde.
En dan zou alles moeten werken naar behoren. Het JFrame laat je misshcien best pas afsluiten als de gebruiker dat wenst (dan ziet deze dat het laden gedaan is).
Wat me net te binnen schiet is dat een JProgressBar ook wel voorzien kon worden van een timer, maar Swing is wel al twee jaar geleden dus dat kan een foute herinnering zijn
.
Ik hoop dat je er nog wat aan hebt.Only art and science can and try to change the world, therefore paying millions to useless sportsmen is sheer idiocy.
The man, the legend: Dijkstrano votes
-
04-06-2007, 23:30 #11Member
- Registered
- 16/09/02
- Location
- Antwerpen
- Posts
- 2,211
- iTrader
- 6 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/2
1. Wat als nu mijn Jframe al gemaakt is in netbeans, maw, de klasse bestaat al.
2. Met laad code bedoel je dan: CsvProgress progress = new CsvProgress(); (dit is mijn Jframe)?
Dit is del aats keer dat ik iets vraag, want kvind het zelf al ambetant te vinden da ge er zoveel moeite in moet steken
.
Het zit dus zo in elkaar:
1. Ik duw op het menuitem "Import csv", dit bevind zich in de HoofdGUi (waar ik begin)
2. HoofdGui gaat naar controller die dan Initialze CSV oproept.
3. Initialize Csv gaat naar klasse Csv en begin daar alles te doen: inlezen en in database zetten.
4. Terwijl dat dit gebeurt zou er een JFrame CsvProgress moeten getoond worden (die al aangemaakt is met GUI builden van netbeans). Deze roep ik op men een Thread CheckCsvDone() waarin ik start() oproep.
Voila, da is het duidelijkste dat ik kan uitleggen
. Kzal allesinds zelf al proberen uit te zoeken wa ge juist bedoeld
.
Bedankt voor de hulp nog is !
no votes
-
05-06-2007, 01:03 #12Member
- Registered
- 17/07/02
- Location
- PSPACE
- Posts
- 4,603
- iTrader
- 14 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/18
Met laad-code bedoelde ik de code die de csv inleest.
Het is namelijk zo dat alles momenteel in dezelfde thread loopt. Als je in die thread een intensieve opdracht laat lopen die niet onmiddellijk returnt, zal heel Swing blijven vasthangen tot die opdracht terug is gekeerd. Enkel je progressbar threaden zal dan niet helpen, omdat die progressbar getoond zal worden nadat je "laad de csv en plaats hem in de db"-code klaar is (dan pas kan Swing je aanvraag om hem te tonen verwerken).
Wat je dus moet doen is de code die de csv laadt en hem in de db plaatst threaden.
Dat de JFrame is aangemaakt met Netbeans is geen probleem, je kan nog steeds de sourcecode editen en dan zo een functie voorzien die de progressbar die in dat frame gebruikt wordt opvraagt om alles te doen zoals ik daarnet ongeveer beschreef.Only art and science can and try to change the world, therefore paying millions to useless sportsmen is sheer idiocy.
The man, the legend: Dijkstrano votes
-
05-06-2007, 01:17 #13Member
- Registered
- 16/09/02
- Location
- Antwerpen
- Posts
- 2,211
- iTrader
- 6 (100%)
- Mentioned
- 0 Post(s)
- Reputation
- 0/2
Ah just, da heb ik al is moeten doen zo
.
Bedankt, kzalt wel werkend krijgen nu ^^
grtzno votes

