Ok, you have the logic to do the search.
Now You need to rewrite the code so it is called on a thread from the action listener
Your old method name of search is better than run.
Welcome to the Java Programming Forums
The professional, friendly Java community. 21,500 members and growing!
The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.
>> REGISTER NOW TO START POSTING
Members have full access to the forums. Advertisements are removed for registered users.
Ok, you have the logic to do the search.
Now You need to rewrite the code so it is called on a thread from the action listener
Your old method name of search is better than run.
Yeah, that will work - but it's a bit nasty! Thread has a run() method. What happens when you instantiate a new Thread is ... nothing. It's not until you invoke the Thread's start() method that an independent execution context starts - see the API documentation for Thread.start(). What you're doing is starting a new FileSearch (which extends Thread) from your actionPerformed which then executes its run() method independently. In the run() method you build a list of directories in the current folder which is saved up until the end of the run method, where you loop over the directories and recursively call the run() method to do the same job again for each directory. It works, but it's a bit nasty!
If I was you I would either: (A) use the list of directories to hold 'work yet to do' and keep looping around until all the work was done, so that your for loop is inside a while loop that only checks to see if it still contains any directories, your for loop finding search matches, or adding new folders to the list of directories or (B) search recursively.
You are currently searching recursively, only in not a very stylish way. You start your FileSearch with an array of files. What you could do in run() is to loop over that array, and for each File, invoke a method (a new one you must write) something like:
If you do it that way, you won't need any ArrayList at all.private void search(File f) { if (f.isDirectory()) for (File child : f.listFiles()) search(child); if (/* f matches our search criteria */) { /* report it */ } }
Please try to compile my code.
Problem is, when I call the run() method recursively it didn't work.
I'm seriously getting lost now and feel I became annoying lol!
What should I do? step by step please !
I'm still working on it though
EDIT : I tried your method, same thing bro
Last edited by hexwind; August 20th, 2011 at 02:44 PM.
My website : MediDev
OK, I see the last version of FileSearch you have put the search parameters as arguments to the run method. Did you read the API documentation for Thread.run(). Can you see what is happening now when you do FileSearch.start() from your actionPerformed method for this version of your code?
I'm not going to compile your code: I know why it doesn't work. You have two good ways of making it work, both of them require FileSearch to extend Thread or at least be Runnable. If you want to all the searching inside your run() method, then you need to keep track of the directories-yet-to-visit somehow. I would take 'list' (the array you originally passed in to the constructor in one FileSearch version) and add the Files to a List (filesToVisit) of some kind. Then use 'while (!filesToVisit.isEmpty())' to keep the loop going until all files are searched. Then inside the while loop, you have your current search code, but starting with 'File current = filesToVisit.remove()'. Check that file to see if it's a directory, and if so, add the files *inside it* to filesToVisit. As you take each file from filesToVisit, it reduces in size. As you discover directories, filesToVisit grows in size and the while loop continues. You will eventually check every file in the list and the while loop will exit, and then so will run().
The other way is to write a 'search' method that works on a single file, but recursively calls itself when it finds a directory with each of the child files in turn. That way is more challenging to understand, but probably less code.
My website : MediDev
ok, here is what I tried to do.
-Create an array File[] list in which i put the abstract pathnames (mysearchpath.listFile())
-Loop through the array and see :
* if it's a file and meets our search criteria : display its name and remove the elemnt from the array
* if it's a directory, add its abstract pathnames to my array
-until the array is empty.
The problem i encountered was that I can't remove an element from an array. Therefore, I switched for ArrayList and added an Iterator in order to remove the elemnts, but I couldn't check the elements of the ArrayList if they are directories or not, as if they are not file objects.
here is my code (without GUI ofc, i just wanted to write it again from scratch and run it on a console)
import java.util.*; import java.io.*; class Search extends Thread{ File file = new File("K:\\Hexwind\\Music\\Opeth"); File[] list = file.listFiles(); ArrayList arList = new ArrayList(); Search(){ for(int i=0; i< list.length; i++) arList.add(list[i]); } ListIterator iterator = arList.listIterator(); public void run (){ int count=0; iterator.next(); while (!arList.isEmpty()){ /*error here */ if ((arlist.get(count).isFile()) && (list[count].toString().endsWith(".mp3"))){ System.out.println(list[count].getName()); iterator.remove(); } /*and here */ else if(arlist[count].isDirectory()){ arList.remove(count); } } } } public class MedFile { public static void main(String[] args){ Search s = new Search(); s.run(); } }
My website : MediDev
There's no need to use those indexes with Lists. You're probably getting errors (though I don't see you updating 'count') because you're using indexes on data structures which may be initially empty or which you remove down to empty. You're seeding (putting original Files in) arlist with your search list before the loop, which is good. You should treat arlist as a list-of-files-yet-to-be-searched, so you'll be removing files from it to search, and adding Files to it when you come across a directory. Your while list is checking isEmpty correctly, you're just not taking Files out and putting Files in quite right. Your loop should be a bit like this (not compiled may contain errors - although I notice both arlist and arList in your code):
while (!arList.isEmpty()) { // take the first entry in the list - taking items is 'working through the list' FIle fCurrent = arList.remove(0); /* must be an item 0 because list is not empty */ if (fCurrent /* is what we seek */) { /* add to list, print or whatever */ } if (fCurrent.isDirectory()) { /* maybe notify directory discovery as progress? */ for (File child : fCurrent.listFiles()) arList.add(child); // new files added to tail of list } }
That should be enough - it should be quite simple code. The problem you have with your List not appearing to contain File objects is because ArrayList can be 'genericized'. If you don't specify a generic type for the ArrayList, I suspect it may be holding Object references:
Lesson: Generics (The Java™ Tutorials > Learning the Java Language)
hexwind (August 20th, 2011)
After a walk and talk and fresh air. I came here again, tried it as you suggested and it worked like a charm :
import java.util.*; import java.io.*; class Search extends Thread{ File file = new File("K:\\Hexwind\\Music\\Opeth"); File[] list = file.listFiles(); // An array that holds the paths of the search file content ArrayList<File> arList = new ArrayList(); // an ArrayList to put the yet-to-search folders(File objects) //In the constructor, I populate the ArrayList with the folders/files of the original search path Search(){ for(int i=0; i< list.length; i++) arList.add(list[i]); } public void run (){ //Loop through the ArrayList until it is empty while (!arList.isEmpty()){ File x = arList.remove(0); //Assign each element to a File object if ((x.isFile()) && (x.getName().endsWith(".mp3"))){ //check if it meets our search criteria System.out.println(x.getName()); // if it does, print its name and arList.remove(0); // remove it from the ArrayList } else if(x.isDirectory()){ //Otherwise, check if it's a directory //if it's a directory, add all its elements to to ArrayList for(File child : x.listFiles()) arList.add(child); } } } } public class MedFile { public static void main(String[] args){ Search s = new Search(); s.run(); } }
Now I tried this with the GUI :
import java.util.*; import java.io.*; import javax.swing.*; class Search extends Thread{ JLabel label; JTextArea area; File file = new File("K:\\Hexwind\\Music\\Opeth"); File[] list = file.listFiles(); // An array that holds the paths of the search file content ArrayList<File> arList = new ArrayList(); // an ArrayList to put the yet-to-search folders(File objects) //In the constructor, I populate the ArrayList with the folders/files of the original search path Search(JLabel label, JTextArea area){ this.label = label; this.area = area; for(int i=0; i< list.length; i++) arList.add(list[i]); } public void run (){ this.label.setText("Search has started"); //Loop through the ArrayList until it is empty while (!arList.isEmpty()){ File x = arList.remove(0); //Assign each element to a File object this.label.setText("Now searching in " + x.getPath()); if ((x.isFile()) && (x.getName().endsWith(".mp3"))){ //check if it meets our search criteria this.area.append(x.getName()+ "\n"); // if it does, print its name and arList.remove(0); // remove it from the ArrayList } else if(x.isDirectory()){ //Otherwise, check if it's a directory //if it's a directory, add all its elements to to ArrayList for(File child : x.listFiles()) arList.add(child); } } this.label.setText("Finished"); } }
Window class - where the GUI is
import java.util.*; import java.io.*; import com.sun.java.swing.plaf.windows.WindowsLookAndFeel; import javax.swing.SwingWorker; import java.awt.*; public class Window extends javax.swing.JFrame { /** Creates new form Window */ public Window() { initComponents(); } /** This method is called from within the constructor to * initialize the form. * WARNING: Do NOT modify this code. The content of this method is * always regenerated by the Form Editor. */ @SuppressWarnings("unchecked") // <editor-fold defaultstate="collapsed" desc="Generated Code"> private void initComponents() { jPanel1 = new javax.swing.JPanel(); jLabel1 = new javax.swing.JLabel(); filetype = new javax.swing.JTextField(); jLabel2 = new javax.swing.JLabel(); path = new javax.swing.JTextField(); jPanel2 = new javax.swing.JPanel(); jLabel3 = new javax.swing.JLabel(); jScrollPane1 = new javax.swing.JScrollPane(); result = new javax.swing.JTextArea(); nowsearching = new javax.swing.JLabel(); jProgressBar1 = new javax.swing.JProgressBar(); searchbutton = new javax.swing.JButton(); setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("")); jLabel1.setText("File Type"); jLabel2.setText("Search Path"); javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1); jPanel1.setLayout(jPanel1Layout); jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(filetype, javax.swing.GroupLayout.DEFAULT_SIZE, 241, Short.MAX_VALUE) .addComponent(jLabel1) .addComponent(jLabel2) .addComponent(path)) .addContainerGap(483, Short.MAX_VALUE)) ); jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(filetype, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(path, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(21, Short.MAX_VALUE)) ); jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("")); jLabel3.setText("Search Result"); result.setColumns(20); result.setEditable(false); result.setRows(5); result.setText("The result will be shown here"); jScrollPane1.setViewportView(result); javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 714, Short.MAX_VALUE) .addComponent(jLabel3) .addComponent(nowsearching) .addComponent(jProgressBar1, javax.swing.GroupLayout.DEFAULT_SIZE, 714, Short.MAX_VALUE)) .addContainerGap()) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jProgressBar1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addComponent(nowsearching)) ); searchbutton.setText("Search"); searchbutton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { searchbuttonActionPerformed(evt); } }); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() .addContainerGap() .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(searchbutton)) .addContainerGap()) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGap(21, 21, 21) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(searchbutton) .addContainerGap(40, Short.MAX_VALUE)) ); pack(); }// </editor-fold> private void searchbuttonActionPerformed(java.awt.event.ActionEvent evt) { // TODO add your handling code here: Search s = new Search(nowsearching, result); s.run(); } /** * @param args the command line arguments */ public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new Window().setVisible(true); } }); } // Variables declaration - do not modify private javax.swing.JTextField filetype; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JPanel jPanel1; private javax.swing.JPanel jPanel2; private javax.swing.JProgressBar jProgressBar1; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JLabel nowsearching; private javax.swing.JTextField path; private javax.swing.JTextArea result; private javax.swing.JButton searchbutton; // End of variables declaration }
It just freezes, and gives me the "finished!" message like before.
My website : MediDev
IT WORKED FINALLY !!!!!!
In the action performed I used
Thanks a LOT guys ! a HELL OF A LOT !new Thread(mythreadname(args)).start();
My website : MediDev