Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using progress bar in file search

Tags:

java

I am writing an application which will search for a particular file or files from the respective path. During searching i need to deploy a progress bar which must run according to the search. so how i can do that? and if possible please post the code?

like image 517
i2ijeya Avatar asked Nov 05 '09 04:11

i2ijeya


4 Answers

This is a tricky question. I don't recall seeing any instance of a non-indexed search showing a progress bar. (Can anyone prove me wrong?)

I'd suggest the following method (an extension of Benny Hallett's suggestion) that might provide more granuity.

Let's assume that you're searching for a specific filename pattern across an entire filesystem (e.g. in unix, searching for all *.jpg files on /)

Start by dividing your progress bar into N pieces (where N is the number of directories in the root path of your search).

Each time you go deeper into the directory heirachy, the total process bar length that was allocated to the parent directory is divided up depending on the number of sub-directories it contains. When the search of a directory is complete, the portion that was allocated to it is added to the progress bar. For even more detail you can further divide the allocation by the number of files + directories in the current directory.

This method should ensure that you only have to traverse the directory structure once and it should handle uneven directories better. (By uneven I mean a mixture of directories with high and low search costs)

As an example, let's assume a directory structure like so:

/
    clipart
    photos
        family    
        holiday
    wallpapers
        anime
        landscapes

(each indent indicates a level deeper in the directory tree and let's assume that all directory traversal is done in alphabetical order)

You start off by looking at '/' and seeing that there are three directories (clipart, photos and wallpapers) and thus you initially divide up the progress bar into thirds.

You then search the clipart directory and when finished, updated your progress bar to one third. You then go inside photos and see that there are two sub-directories. This then means that when you finish searching family you add one sixth to the progress bar as there are two sub-directories (family and holiday) and progress against each one of these constitutes one half the one third allocated to photos.

So in summary:

completion of clipart adds one third

completion of photos/family adds one sixth

completion of photos/holiday adds one sixth

completion of wallpapers/anime adds one sixth

completion of wallpapers/landscapes adds one sixth

For a total of 1.0 (or 100%) (ignoring floating point precision)

like image 141
Catchwa Avatar answered Oct 31 '22 05:10

Catchwa


To use most Progress Bar controls you'll need to know 2 things.

  • How many things you need to do
  • How many things you have done

For the first one, it'd probably be good to use the number of files in the directory (for a single directory) or the number of subdirectories (for recursively accessing directories)

Secondly, you'd want to update the progress bar every time you process a file or directory.

There's a tutorial for using Progress Bars in Swing: here

The basic code you'll need is

JProgressBar progressBar = new JProgressBar(0, getNumberOfFiles());

And then update it using

progressBar.setValue(getCurrentNumberProcessed());

If the initial number of files or directories is unknown, you can call progressBar.setIndeterminate(true) to create one of those I have no idea how long this will take progress bars. From there you can work out how many files or directories you need to process before doing

progressBar.setIndeterminate(false);
progressBar.setMaximum(numberOfFiles);
like image 23
Benny Hallett Avatar answered Oct 31 '22 07:10

Benny Hallett


Your search Program(SearchFile class - preferably singleton) should have a field which is being updated as the search progresses. For example private double searchProgress; and then update this field during the actual search.

double searchProgress = 100/noOfTotalFiles;
searchProgress = searchProgress + searchProgressIncrement;

And provide a public getter method for your search program.

public double getProgress(){ return searchProgress;}

Step2: Use a simple Thread to poll the progress for every sec(as you required) from calling Program.

progressBar.setIndeterminate(false);            
progressBar.setMaximum(100);

Thread t = new Thread(){

   @override 
   public void run(){
      progressBar.setValue((int)SearchFile.getProgress());
   }

}

Make sure that you have proper logic to know how long you run this thread periodically. For example, update a flag in SearchFile that says the search is done.

while(SearchFile.isRunning()){
       Thread.sleep(1000); //sleep for 1 sec
       progressBar.setValue((int)SearchFile.getProgress());
}

you can still improve this ...

like image 21
ipy Avatar answered Oct 31 '22 06:10

ipy


I used Catchwa's method. I set the progress range to 14000 because the OSes on my system have about that many dirs. When I found an empty dir, I added the fractional, weighted amount to the progress bar. The amount being based on the depth and normalized with the range. In every subtree traversal you eventually end up with an empty dir and the weight of all the empty subdirs in a dir comprise the weight of the dir, but broken into chunks. When I found a non-empty dir I stored the number of subdirs in a map. I got, using Qt:

emit findProgressBar_setRange(14000);
...
if (dir.size()) {
    m_dirsAtDepth[++m_depth] = dir.size();
}
else {
    qreal product = 1.00;
    for (int i = 1; i <= m_depth; ++i) {
        product *= m_dirsAtDepth[i];
    }
    int x = qRound((1.00 / product) * 14000);
    emit findProgressBar_addValue(x);
}

It runs pretty smooth and it's cheap. I also offer the user an accurate progress bar option where I count the total number of dirs first, which can be expensive.

like image 29
shawno Avatar answered Oct 31 '22 07:10

shawno