スレッドコールバック


スレッドコールバックの例はjavaeyeの質問回答領域から抜粋します.
 
package cn.edu.xupt.chapter01.knight;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

/**
 * Title:             <br>
 * Description:     ,        <br>
 * Description:         ,              Copyright: Copyright (c) 2009<br>
 * Company: UFIDA<br>
 * 
 * @author cjy
 * @version 1.0
 */
public class TestCallable extends JFrame implements KeyListener, ActionListener {

	/**
	 *    
	 */
	private static final long serialVersionUID = -11026086618847428L;
	/**      */
	private CallableBO bo = new CallableBO();
	/**     */
	private JTextArea textArea;
	/**      */
	private JScrollPane jscroll;
	/**        */
	private JTextField field;
	/**      */
	private JButton okButton;
	/**      */
	private JButton clearButton;

	/**
	 *    
	 */
	public TestCallable() {

		//      
		textArea = new JTextArea();
		textArea.setEditable(false);
		jscroll = new JScrollPane(textArea);
		JLabel label = new JLabel("         (  file     ):");
		field = new JTextField();
		field.setPreferredSize(new Dimension(200, 25));
		field.addKeyListener(this);
		JPanel commPanel = new JPanel();
		okButton = new JButton("  ");
		okButton.addActionListener(this);
		clearButton = new JButton("  ");
		clearButton.addActionListener(this);
		commPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
		commPanel.add(label);
		commPanel.add(field);
		commPanel.add(okButton);
		commPanel.add(clearButton);
		//     
		Container con = this.getContentPane();
		con.setLayout(new BorderLayout());
		con.setPreferredSize(new Dimension(600, 400));
		con.add(commPanel, BorderLayout.NORTH);
		con.add(jscroll, BorderLayout.CENTER);

		this.setVisible(true);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		pack();
	}

	public static void main(String[] args) {

		SwingUtilities.invokeLater(new Runnable() {

			public void run() {
				new TestCallable();
			}

		});
	}

	public void keyTyped(KeyEvent e) {

	}

	public void keyPressed(KeyEvent e) {

	}

	public void keyReleased(KeyEvent e) {
		if (e.getKeyCode() == java.awt.event.KeyEvent.VK_ENTER) {
			onExe();
		}
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource().equals(okButton)) {
			onExe();
		} else if (e.getSource().equals(clearButton)) {
			textArea.setText("");
			field.setText("");
		}
	}

	/**
	 *          
	 */
	private void onExe() {
		String text = field.getText();
		if (text != null && !text.equals("")) {
			System.out.println(text);
			//     file
			if (text.equals("file")) {
				final JFileChooser jf = new JFileChooser("Title...");
				jf.setDialogTitle("         ...");
				SwingUtilities.invokeLater(new Runnable() {

					public void run() {
						int result = jf.showOpenDialog(TestCallable.this);
						jf.setVisible(true);
						File selectedFile = null;
						if (result == JFileChooser.APPROVE_OPTION) {
							selectedFile = jf.getSelectedFile();
							if (selectedFile.exists()) {
								textArea
										.setText(bo.exe(selectedFile.getPath()));
								return;
							}
						}
					}
				});

			} else {
				textArea.setText(bo.exe(text));
			}
		}
	}

}

class CallableBO {

	/**
	 *     
	 * 
	 * @param comm
	 * @return
	 */
	public String exe(String comm) {
		try {
			Runtime rt = Runtime.getRuntime();
			Process proc = rt.exec(comm);
			ExecutorService pool = Executors.newFixedThreadPool(3);
			Callable<String> err = new S(proc.getErrorStream(), "    ");
			Callable<String> out = new S(proc.getInputStream(), "    ");
			Future<String> e = pool.submit(err);
			Future<String> o = pool.submit(out);
			return o.get() + "
" + e.get(); } catch (InterruptedException e1) { e1.printStackTrace(); } catch (ExecutionException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return null; } private final class S implements Callable<String> { /** */ private StringBuffer msg = new StringBuffer(); /** */ private InputStream is; /** */ private String msgType; public S(InputStream is, String msgType) { this.is = is; this.msgType = msgType; } public String call() { try { InputStreamReader isr = new InputStreamReader(is); BufferedReader br = new BufferedReader(isr); String line = null; msg.append(msgType + ":
"); while ((line = br.readLine()) != null) { if (!line.equals("")) { System.out.println(msgType + ">" + line); msg.append(line + "
"); } } return msg.toString(); } catch (IOException ioe) { ioe.printStackTrace(); return null; } } } }