java - System.in 上的 readLine,无需挂起 Swing GUI 线程

标签 java multithreading swing

我有以下代码,应该将 System.in 重定向到 JTextField。但每当我尝试 new BufferedReader(new InputStreamReader(System.in)).readLine(); ,Swing GUI 挂起。如何在不挂起 GUI 线程的情况下从 System.in 读取行?

private static LinkedBlockingQueue<Character> sb = new LinkedBlockingQueue<Character>();
BufferedInputStream s = new BufferedInputStream(new InputStream() {
    int c = -1;

    @Override
    public int read() throws IOException {
        Thread thread = new Thread(new Runnable() {

            @Override
            public void run() {
                try {
                    c = sb.take();
                } catch (InterruptedException ie) {
                    ie.printStackTrace();
                }
            }
        });
        thread.start();
        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return c;
    }
});
JTextField t = new JTextField();
    t.addKeyListener(new KeyListener() {
        @Override
        public void keyTyped(final KeyEvent e) {
            sb.offer(e.getKeyChar());
            if (e.getKeyChar() == '\n' || e.getKeyChar() == '\r') {
                t.setText("");
            }
        }

        @Override
        public void keyPressed(KeyEvent arg0) {
        }

        @Override
        public void keyReleased(KeyEvent arg0) {
        }
    });

System.setIn(s);

最佳答案

定义一个Callback类,这里我用的是接口(interface),你可以跳过这个阶段。

interface Callback {
    void updateText(String s);
}

public class  CallbackImpl implements Callback  {// implements this interface so that the caller can call text.setText(s) to update the text field.

    JTextField text;// This is the filed where you need to update on.

    CallbackImpl(JTextField text){//we need to find a way for CallbackImpl to get access to the JTextFiled instance, say pass the instance in the constructor, this is a way.
     this.text=text;
    }

    void updateText(String s){
         text.setText(s);//updated the text field, this will be call after getting the result from console.
    } 
}

定义一个执行作业的线程,并在作业(从控制台读取)完成后调用回调方法。

class MyRunable implements Runnable {

    Callback c; // need a callable instance to update the text filed

    public MyRunable(Callback c) {// pass the callback when init your thread
        this.c = c;
    }

    public void run() {
        String s=// some work reading from System.in
        this.c.updateText(s); // after everything is done, call the callback method to update the text to the JTextField.
    }

}

要使其正常工作,请在您的监听器上启动此线程:

new Thread(new MyRunable(new CallbackImpl(yourJtextFiled))).start();//start another thread to get the input from console and update it to the text field.

关于java - System.in 上的 readLine,无需挂起 Swing GUI 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27351636/

相关文章:

python - 删除线程定时器类?

java - WAIT 和 BLOCKED 线程状态的区别

java - 从另一个 Swing 类向 Swing 类返回一个值

java - 在 for 循环 JAVA 中定义方法

java - 使用行分隔符获取额外的行

Java插件JVM参数

java - 如何编写 jXLS 模板以及在何处编写

multithreading - 在 Perl 中,如何从父进程向子进程发送消息(或信号),反之亦然?

java - 多个组件 "linked"相互

java - 从 Java 管理动态 JavaScript 的最佳实践是什么?