Java如何扩展InputStream以从JTextField读取数据?

4
在一个项目中,我学会了如何通过控制台窗口运行Java应用程序。在这里,由于社区的帮助,我成功地解决了从进程中输出数据的问题,但我的命令行应用程序仍然会不断报错,因为没有输入流。

根据上一个回复,我认为我应该采用类似的方法来实现JTextFieldInputStream extends InputStream,但是在Javadoc和整个Google和互联网上寻找这样的类时,我真的没有找到任何解释如何实现它的说明。

因此,我想要一些链接、示例、教程或样例代码,就像以前的主题那样。只要给我一个扩展InputStream的类,可以在我按Enter时从JTextField中读取,我将通过实现并使其正常工作来完成剩下的事情!提前感谢!

抱歉,我有点困惑,你的应用程序是基于命令行还是窗口界面? - Rorchackh
基于窗口的应用程序。它在其中运行基于命令行的.class文件,例如它将调用一个名为java HelloWorldInput的进程,该进程是基于命令行的,并且需要输入,我希望可以从我的应用程序中的JTextField中检索到。我无法提供代码,它包含6个文件和500多行代码... :/ - Angelos Chalaris
你应该从哪里获取输入,是从JTextField还是控制台?而且,为什么需要一个inputstream从JTextField读取?为什么不选择更简单的方式呢? - Victor Mukherjee
我的JTextField有几个可观察的原因,所以显然当按下Enter键时,奇怪的事情已经发生了!:P 我应该将进程的输入流重定向到一个我需要帮助的inputstream子类,以便从JTextField而不是控制台中获取输入。如果你有更简单的方法(无论是监听器还是其他方式),请给我一些提示.. :) - Angelos Chalaris
InputStream is = new ByteArrayInputStream(myTextField.getText().getBytes(Charset.forName("UTF-8")));有什么问题吗? - Crozin
2个回答

10
我不明白为什么你需要一个扩展InputStream的JTextField?基本上,你需要做以下几点:
  1. 在JTextField上添加一个ActionListener(即当用户按下Enter键时,将调用actionPerformed方法)
  2. 使用getText()获取JTextField的文本
  3. 然后使用new ByteArrayInputStream(text.getBytes("UTF-8"))将字符串文本转换成输入流InputStream
这里有一小段代码,可以帮助你了解基本思路:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class TestTextField {

    private void initUI() {
        JFrame frame = new JFrame(TestTextField.class.getSimpleName());
        frame.setLayout(new FlowLayout());
        final JTextField textfield = new JTextField(20);
        textfield.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                try {
                    String text = textfield.getText();
                    InputStream is = new ByteArrayInputStream(text.getBytes("UTF-8"));
                    // Here do something with your input stream (something non-blocking)
                    System.err.println(text);
                } catch (UnsupportedEncodingException e1) {
                    e1.printStackTrace();
                }

            }
        });
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(textfield);
        frame.setSize(300, 300);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestTextField().initUI();
            }
        });
    }

}

现在有一个ActionListener的问题,因为我还有另一个用于其他目的,所以基本上当我从apache commons exec调用外部进程时,我需要一个InputStream传递给它,以便它能够从某个地方读取一些数据。所以显然ActionListener不是我要找的东西...除非我忽略了什么... - Angelos Chalaris
1
@Spiritios 拥有多个ActionListener并不是问题。你所拥有的ActionListener很可能与我在答案中提到的那个是相同的。我几乎99%确定这是正确的方法,所以你可能正在忽略它;-)。 - Guillaume Polet
嗯,好的...但我正在使用Apache Commons PumpStreamHandler,基本上我需要一个InputStream传递给它的构造函数,以便被调用的子进程使用,所以这可以通过Listeners实现吗? :O - Angelos Chalaris
@Spiritios 我添加了一个示例代码,应该可以让你基本了解如何操作。在动作监听器中,你可以调用你的Apache commons pumpstreamhandler等等... - Guillaume Polet
1
这是对原问题更好的答案。 - Hovercraft Full Of Eels

4
这个实现方案怎么样?
import java.io.IOException;
import java.io.InputStream;

import javax.swing.JTextField;


public class JTextFieldInputStream extends InputStream {
    byte[] contents;
    int pointer = 0;

    public JTextFieldInputStream(final JTextField text) {

        text.addKeyListener(new KeyAdapter() {
            @Override
            public void keyReleased(KeyEvent e) {
                if(e.getKeyChar()=='\n'){
                    contents = text.getText().getBytes();
                    pointer = 0;
                    text.setText("");
                }
                super.keyReleased(e);
            }
        });
    }

    @Override
    public int read() throws IOException {
        if(pointer >= contents.length) return -1;
        return this.contents[pointer++];
    }

}

要使用此输入流,请按照以下步骤进行操作:

 InputStream in = new JTextFieldInputStream( someTextField );
 char c;
 while( (c = in.read()) != -1){
    //do whatever with c
 }

我按 Enter 键时才读吗?

当调用in.read()时它就开始读取,如果返回值为-1,则表示流的结尾。

(我能否修改以使“Enter”键清空JTextField?)

您需要添加一个动作监听器,而这个功能与输入流的工作无关。


我不太明白你的确切意思,但是我对InputStream进行了一些更稳定的更改。 - user1406062
1
现在这很简单,我要检查一下,非常感谢您的帮助。顺便问一下,我按回车键时它只读吗?(我能否修改使Enter键清空JTextField?):D - Angelos Chalaris
如果您希望输入流具有动态性,那么这可能会有些困难。一旦文本被编辑,指针是否应该返回到零? - user1406062
2
我已经更新了我的答案,但从未测试过。所以,如果它失败了,你不应该生我的气。 - user1406062
1
为了你所做的一切,我永远不会生你的气,我只能感激你花时间帮助我! :) - Angelos Chalaris
显示剩余8条评论

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