java - Swing Worker and GUI update -


i'm new community!

i want ask swingworker , relationship gui.

i know there answered questions swingworker, , i've read lot of them, taking helpful advices.

now i'd post code wrote basic application counts number of files , folders specified directory.

since search take lot of time, want progress bar displayed during process. also, users have possibility of stopping count process clicking button or closing frame contains progress bar.

here there questions on code posted below:

  • the call execute() method swingworker last instruction of waitingframe constructor: there better place it?
  • the dispose() method waitingframe called swingworker's done() method, correct? if count process fast, dispose method called before waiting frame visible? result, have 2 open frames...
  • is there better method interrupt process , manage message dialogs shown users? used 2 boolean variables, valid , interrupted, achieve purpose...

and here's code:

import java.awt.*; import java.awt.event.*; import java.io.file; import java.io.ioexception; import javax.swing.*; import javax.swing.border.*; public class countfiles {     public static void main(string[] args)throws exception     {         swingutilities.invokelater(new runnable(){             public void run(){                 try                 {                     uimanager.setlookandfeel(uimanager.getsystemlookandfeelclassname());                     new countfilesframe().setvisible(true);                 }                 catch(exception ex){                     ex.printstacktrace();                 }             }         });     } } class countfilesframe extends jframe {     private jtextfield field;     public countfilesframe()     {         super("conta file e cartelle");         setdefaultcloseoperation(exit_on_close);         setresizable(false);         jpanel pane=(jpanel)getcontentpane();         pane.setbackground(color.white);         pane.setborder(new emptyborder(5,20,5,20));         jpanel center=new styledpanel(pane,borderlayout.center,new flowlayout(flowlayout.left,5,10)),bottom=new styledpanel(pane,borderlayout.south,new flowlayout(flowlayout.left,20,0));         // center panel         center.add(new jlabel("cartella :"));         string text="";         try{             file folder=new file("../");             text=folder.exists()?folder.getcanonicalpath():"";         }         catch(exception ex){}         field=new jtextfield(text,25);         center.add(field);         // jtextarea         string newline=system.getproperty("line.separator"),message="scegliere la cartella da cui far partire la ricerca."+newline+         "sara' contato il numero di file e di cartelle presenti "+newline+"nella directory inserita e in tutte le sottocartelle";         jtextarea area=new jtextarea(message);         area.seteditable(false);         area.setfont(field.getfont());         pane.add(area,borderlayout.north);         // bottom panel         bottom.add(new jbutton(new abstractaction("cambia cartella"){             public void actionperformed(actionevent e){                 changedirectory();             }         }));         bottom.add(new jbutton(new abstractaction("inizia ricerca"){             public void actionperformed(actionevent e){                 new waitingframe(countfilesframe.this);             }         }));         pack();         setlocationrelativeto(null);     }     public void changedirectory()     {         jfilechooser chooser=new jfilechooser(field.gettext());         chooser.setdialogtitle("cambia cartella");         chooser.setfileselectionmode(jfilechooser.directories_only);         if(chooser.showdialog(this,"scegli")==jfilechooser.approve_option)         {             try             {                 file selected=chooser.getselectedfile();                 if(selected.exists())field.settext(selected.getcanonicalpath());             }             catch(exception ex){}         }     }     private class waitingframe extends jframe     {         private counter counter;         public waitingframe(countfilesframe f)         {             super("ricerca file");             setdefaultcloseoperation(dispose_on_close);             addwindowlistener(new windowadapter(){                 public void windowclosing(windowevent e){                     stopcounter();                 }             });             setresizable(false);             jpanel pane=(jpanel)getcontentpane(),buttonpanel=new styledpanel(pane,borderlayout.south,new flowlayout(flowlayout.center,0,10));             jlabel label=new jlabel("conteggio in corso...",jlabel.center);             label.setborder(new emptyborder(0,0,10,0));             pane.add(label,borderlayout.north);             pane.setbackground(color.white);             pane.setborder(new emptyborder(10,40,0,40));             jprogressbar progressbar=new jprogressbar(0,100);             progressbar.setborderpainted(false);             progressbar.setindeterminate(true);             pane.add(progressbar,borderlayout.center);             buttonpanel.add(new jbutton(new abstractaction("annulla"){                 public void actionperformed(actionevent e){                     stopcounter();                 }                    }));             while(pane.getsize().width!=pane.getpreferredsize().width)pack();             setlocationrelativeto(null);             setvisible(true);             (counter=new counter()).execute();         }         public void stopcounter()         {             counter.interrupt();             counter.cancel(true);         }         private class counter extends swingworker<void,void>         {             private boolean valid=true,interrupted=false;             private int filesnumber=0,foldersnumber=0;             protected void doinbackground()             {                 file folder=new file(field.gettext());                 if(!folder.exists()||!folder.isdirectory())valid=false;                 else countfiles(folder);                 return null;             }             protected void done()             {                 dispose();                 if(interrupted)return;                 else if(!valid)joptionpane.showmessagedialog(countfilesframe.this,"inserire una cartella valida","percorso specificato errato",joptionpane.error_message);                 else joptionpane.showmessagedialog(countfilesframe.this,"sono stati trovati "+(foldersnumber-1)+" cartelle e "+filesnumber+" file","ricerca completata",joptionpane.information_message);             }             private void countfiles(file file)             {                 if(file.isdirectory())                 {                     foldersnumber++;                     for(file nested:file.listfiles())countfiles(nested);                             }                 else filesnumber++;             }             public void interrupt()             {                 interrupted=true;             }         }     } } class styledpanel extends jpanel {     public styledpanel(jpanel parent,string position,layoutmanager layout)     {         super(layout);         setbackground(color.white);         parent.add(this,position);     } } 

i posted application code, can try compile , run it.

thanks in advance help!

ps: didn't change interface language, i'm sorry that. also, i'm sorry bad english...

the call execute() method swingworker last instruction of waitingframe constructor: there better place it?

there nothing wrong how calling it.

the dispose() method waitingframe called swingworker's done() method, correct? if count process fast, dispose method called before waiting frame visible? result, have 2 open frames...

it correct , situation describe cannot happen. swingworker.done() called on edt via delayed swingutilities.invokelater call , called jframe.setvisible(true) before constructing swingworker (on edt).

instead of multiple frames, consider using dialog, perhaps modal 1 if attempting block user input (like here).

is there better method interrupt process , manage message dialogs shown users? used 2 boolean variables, valid , interrupted, achieve purpose...

there better way of doing this, considering current code dangerously close not being thread safe. consider using atomicboolean instead of boolean if both edt , swing worker need access 2 members.

you should check interrupted flag somewhere , exit file listing loop upon changing.

you can wrap swing code swingutilities.invokelater call anywhere inside swingworker.doinbackground() fine grained gui updates. doing has same effect if done() had been invoked control when , how many times called. check here code example. own code pass execution main thread edt inside main() method (the reason code pattern swing code must execute on edt).


Comments

Popular posts from this blog

sequelize.js - Sequelize group by with association includes id -

android - Robolectric "INTERNET permission is required" -

java - Android raising EPERM (Operation not permitted) when attempting to send UDP packet after network connection -