Sign In/My Account | View Cart  

advertisement

AddThis Social Bookmark Button

Listen Print Discuss

Controlling Threads by Example
Pages: 1, 2, 3, 4

A class model in Figure 3 illustrates the design.

Figure 3.
Figure 3. Class diagram for Search/Stop functionality

The FileFinder.java class is responsible for finding all files under the root directory and contains the string token. The constructor takes in the File object for the root directory. The findFiles(..) method returns the list of File objects. The usage of the FileFinder class looks as follows:

FileFinder finder = new FileFinder(dirFile);
List javaFiles = finder.findFiles(token);

We are not going to spend time looking at the algorithm. I would encourage you to look at the complete source for each iteration before proceeding with the next iteration. SearchForm.java SearchForm class will present a swing interface to the user and display the output when the user clicks on the Search button. The constructor starts by setting the size of the window. It adds all the SWING components to the JFrame contentPane. To handle the button clicks, SearchForm implements an ActionListener interface. Listeners are a common mechanism used in SWING to handle the user actions from the screen. The SearchForm.actionPerformed(..) method implements the functionality when either the Directory, Search, or Cancel buttons are clicked. When the Directory button is clicked, a JFileChooser is displayed where a directory can be chosen. See the zip file for the actual code. When the Search button is clicked, a separate thread should be invoked to kick off the search process using the SearchThread class. Here is a snippet of the class:

public class SearchForm extends JFrame 
        implements ActionListener {

    private JButton dirButton 
        = new JButton("Choose Directory");
    private JButton searchButton 
        = new JButton("Search");
    private JTextArea area 
        = new JTextArea();
    private JTextField tokenField 
        = new JTextField("");

    public SearchForm() {

        // set the initial size
        setSize(600, 300);

        // Exit the application on window close
        this.setDefaultCloseOperation(
                JFrame.EXIT_ON_CLOSE);

        ((JPanel) getContentPane()).setBorder(
          BorderFactory.createEmptyBorder(
                5, 5, 5, 5));

         ....

        // add the panels to the frame
        getContentPane().add("North", 
                northPanel);
        getContentPane().add("Center", 
                new JScrollPane(area));
        getContentPane().add("South", 
                southPanel);
    }

    public static void main(String[] args) {
        SearchForm form = new SearchForm();
        form.setVisible(true);
    }

    /**
     * Act on the button click from the user
     */
    public void actionPerformed(ActionEvent e){
        // open a file dialog and let the 
        // user choose a file
        Object source = e.getSource();

        if (source == dirButton) {
             ....

        } else if (source == searchButton) {
             ....
        }

    }

    public void setTextArea(List javaFiles) {
        ....
    }
}

SearchThread.java: To create a new thread for search, we need to extend the Thread class. A new class, called the SearchThread, is created as follows:

public class SearchThread extends Thread {

    private File rootDir;
    private String token;
    private SearchForm form;

    public SearchThread(File rootDir, 
        String token, SearchForm form) {
        
        this.rootDir = rootDir;
        this.token = token;
        this.form = form;
    }

    public void run() {
        FileFinder finder 
                = new FileFinder(rootDir);
        List javaFiles 
                = finder.findFiles(token);
        form.setTextArea(javaFiles);
    }

}

The constructor takes in the root directory, the token, and the SearchForm itself (so that the output can be displayed on the screen). Note that the FileFinder class is now used from the SearchThread. The thread itself is invoked when the user clicks on the Search button as follows:

// Invoke the search on a different Thread
File dirFile = new File(dirName);
String token = tokenField.getText();
sThread 
        = new SearchThread(dirFile,token,this);
sThread.start();

Note that the variable sThread is now a member variable of the class SearchForm. Once the thread is started, the SWING event dispatching the thread is free to do other operations. One important operation that the user can do after starting a search is to stop the search. Note that the search thread calls the method:

form.setTextArea(javaFiles);

to show the files on the text area in the middle of the screen. One of the golden rules of SWING is that, all screen changes (almost) need to be done from the SWING event dispatching thread. However, here we seem to be doing it from the search thread. Let's see the implementation of the form.setTextArea(..):

public void setTextArea(List javaFiles) {
    StringBuffer areaBuffer     
        = new StringBuffer();
    Iterator fileIter 
        = javaFiles.iterator();
        
    while (fileIter.hasNext()) {
        File file 
                = (File) fileIter.next();
        areaBuffer.append(
                file.getAbsolutePath())
                .append('\n');
    }

    if ("".equals(areaBuffer.toString())){
        areaBuffer.append(
                "No Files Found !!!");
    }

    SwingUtilities.invokeLater(
        new SetAreaRunner(area, 
                areaBuffer.toString()));
}

Pages: 1, 2, 3, 4

Next Pagearrow