如何让System.in从JTextField中读取数据

3

我正在尝试让System.in InputStream从JTextField中读取内容。

我需要它能够允许.read()在用户在JTextField中输入字符串并按下回车后继续执行。

问题是我不知道何时调用.read(),我希望它能够阻塞线程但不会冻结主线程,直到用户在JTextField中按下回车,然后它将通知等待的线程。

到目前为止,我尝试了以下方法:

public class InputStreamHandlerThread extends Thread {

    private JTextField txt;
    public InputStreamHandlerThread(JTextField txt) {
        this.txt = txt;
        start();
    }

    @Override
    public void run() {
        System.setIn(new FakeInputStream());
    }

    class FakeInputStream extends InputStream {
        private int indx = 0;

        @Override
        public int read() throws IOException {
            if (indx == txt.getText().length()) {
                indx = 0;
                try {
                    synchronized (this) {
                        wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            int byt = txt.getText().getBytes()[indx];
            indx++;
            return byt;

        }
    }
}

这个类由GUI线程初始化并启动。一旦GUI加载完成,它就创建了这个类的一个实例,并保留一个指针,以便在JTextField中按下键盘上的回车键时通知它读取其中的内容。

       in = new JTextField();
       in.addKeyListener(new KeyAdapter() {
            @Override
            public void keyTyped(KeyEvent a) {
                if (a.getKeyChar() == '\n') {
                    inputStreamHandler.notify();
                }
            }
        });

目前有三个线程:
1. 运行GUI的主线程
2. 输入流处理程序线程(见上文^)
3. 从System.in读取的线程

问题在于,一旦我调用 inputStreamHandler.notify(); ,它会抛出一个 java.lang.IllegalMonitorStateException 异常,根据文档,如果线程不是锁的持有者,则抛出此异常。如何解决这个问题呢?
谢谢 :-)

2
使用ActionListener,当它被触发时,将文本添加到一个BlockingQueue中,从中您的FakeInputStream可以读取。 - MadProgrammer
还要记住,Swing 不是线程安全的,因此您的线程实际上读取什么是不确定的。 - MadProgrammer
@tobias_k 这是一个文本字段而不是文本区域 :) MadProgrammer 我会尽快查看,谢谢!!! - fill͡pant͡
1
请允许我问一下,您为什么想要System.inJTextField中读取?此外,您是希望流在每次键入时都进行读取,还是只有在用户按下Enter键时才读取? - user1803551
@user1803551 我正在制作一个程序,允许您将任何设计为在命令行中运行的Java程序加载到可自定义的GUI中。因此,我需要覆盖PrintStreams(已完成)和Input stream(在MadProgrammer的解决方案之后完成)。正如我在主帖中所说,我想在按Enter键后流式传输字节,这就是为什么我在键事件之后有条件的原因。现在它已经解决了!我会将解决方案发布为答案,供那些仍然感兴趣的人使用 :- ) - fill͡pant͡
1个回答

0
String text;

...

in.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e){
        text = in.getText();
    }
});

请确保在两个字段中都输入文本。


谢谢您的回复,但那不是我要找的... 就像我说的, “我正在尝试使System.in InputStream从JTextField中读取。” 我知道如何从JTextComponent中检索文本,但我不知道如何将其提供并创建一个类来像InputStream一样读取。 - fill͡pant͡

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接