FileFinder finder = new FileFinder(dirFile); List javaFiles = finder.findFiles(token);전에 완전한 소스코드를 살펴 보시기를 권장합니다. SearchForm.java의 SearchForm 클래스는 사용자를 위한 swing 인터페이스(화면)와 사용자가 검색 버튼을 클릭했을 때 결과를 보여주는 일을 합니다. 생성자는 화면 크기를 설정하는 일부터 시작해서 모든 SWING 컴포넌트들을 JFrame contentPane에 추가합니다. 버튼 클릭을 다루기 위해서 SearchForm은 ActionListener 인터페이스를 구현했습니다. 리스너는 SWING에서 사용자가 화면을 통해 발생시키는 행위를 처리하기 위해 사용하는 일반적인 메커니즘입니다. SearchForm.actionPerformed(..) 메소드는 디렉터리, 검색, 취소 버튼들이 클릭 했을 때 필요한 기능을 구현했습니다. 디렉터리 버튼이 클릭하면 JFileChooser를 사용하여 선택할 수 있는 디렉터리를 보여줍니다. zip파일에서 실제 코드를 확인하세요. 검색 버튼을 클릭하면 별도의 쓰레드가 SearchThread 클래스를 사용하여 검색 프로세스를 시작하기 위해 호출되어야 합니다.
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: 검색을 위한 새로운 쓰레드를 만들기 위해서 Thread 클래스를 상속합니다. SearchThread 클래스는 아래처럼 만들었습니다.
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); } }생성자에 루트 디렉토리와 검색할 키워드(token) 그리고 SearchForm 자신을 인자로 넘겨 줍니다(이렇게 하는 이유는 화면에 결과를 출력하기 위해서 입니다.). FIleFinder 클래스가 SearchTread에서 사용된다는 것을 확인하시기 바랍니다. 사용자가 검색 버튼을 클릭하면 아래의 코드처럼 쓰레드가 호출됩니다.
// Invoke the search on a different Thread File dirFile = new File(dirName); String token = tokenField.getText(); sThread = new SearchThread(dirFile,token,this); sThread.start();sThead는 SearchForm 클래스의 멤버 변수라는 것에 유의하시기 바랍니다. 한 번 쓰레드가 시작하면 SWING의 Event Dispatching Thread는 다른 기능들을 자유롭게 할 수 있습니다. 검색이 시작된 후에 사용자가 할 수 있는 가장 중요한 기능은 검색을 멈추는 것입니다. 검색 쓰레드가 호출하는 다음의 메소드에 주목하시기 바랍니다.
form.setTextArea(javaFiles);화면 가운데 있는 text area에 파일들을 보여 주기 위한 것입니다. SWING의 철칙 중 하나로 (거의)모든 화면을 변경하는 작업들은 SWING의 Event Dispatching Thread에 의해 수행 될 필요가 있습니다. 하지만 지금은 검색 쓰레드에서 그 작업을 하고 있는 것처럼 보입니다. 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())); }SWING 지지자들 이라면 SwingUtilities.invokeLater가 문제를 해결했다는 것을 즉시 알아차렸을 것입니다. setTextArea(..) 메소드는 먼저 파일 리스트로부터 문자열을 만들고 invokerLater(..)를 호출하여 화면의 text area 필드에 설정합니다. 코드를 SwingUtilities.invokeLater(..)로 감싸서 효율적으로 Event Dispatcher Thread에서 호출할 수 있도록 합니다. invokeLater 메소드는 단순히 Event Dispatcher 큐에 Runnable 객체를 차례대로 관리합니다. SWING의 Event Dispatcher Thread는 메시지를 읽고 run() 메소드 안에 있는 코드를 실행합니다. Figure 4는 사용자가 검색 버튼을 클릭했을 때 어떤 일이 일어나는지 시퀀스 다이어그램으로 보여줍니다.
if (sThread != null) { sThread.interrupt(); }SearchThread 클래스는 검색에 관한 모든 기능을 FileFinder 클래스에게 위임하고 있습니다. 따라서 어떻게 해서든지 FileFinder 클래스는 검색 쓰레드가 중단됐다는 것을 알 수 있어야 합니다. 어떤 쓰레드가 중단 됐는지는 다음의 코드로 확인할 수 있습니다:
이전 글 : ASP.NET AJAX의 세 가지 얼굴 - (3)
다음 글 : 예제로 살펴보는 쓰레드 제어하기 - (2)
최신 콘텐츠