【问题标题】:Java-How to extend InputStream to read from a JTextField?Java-如何扩展 InputStream 以从 JTextField 中读取?
【发布时间】:2012-10-01 07:54:50
【问题描述】:

在做一个项目时,我开始通过一个类似控制台的小窗口运行 java 应用程序。感谢这里的精彩社区,我设法solve the problem with outputting the data from a proccess,但由于没有输入流,我运行的命令行应用程序会不断出错。

基于该线程中的最后一个有用的回复,我想我将类似地处理JTextFieldInputStream extends InputStream 实现,但是在 javadocs 以及整个谷歌和互联网中寻找一些可以做到的类,我真的没有发现任何解释如何做这个。

所以我要求提供一些链接、示例、教程、示例代码,就像在上一个主题中一样。 只给我一个扩展 InputStream 的类,当我按下 Enter 键时,它可以扩展为从 JTextField 读取,剩下的我将完成它并使其工作!提前致谢!

【问题讨论】:

  • 对不起,我很困惑,您的应用程序是基于命令行的还是基于窗口的?
  • 基于窗口。它在其中运行基于命令行的 .class 文件,例如它将调用一个进程java HelloWorldInput,它是基于命令行的,需要我希望可以从我的应用程序中的 JTextField 中检索的输入。我无法提供代码,大约是 6 个文件,总共 500 多行代码...:/
  • 你应该从哪里获取输入,JTextField 或控制台,无论如何,你为什么需要一个输入流来从 JTextField 中读取?为什么不走更简单的路呢?
  • 我的 JTextField 是可观察的有几个原因,所以很明显,当按下 Enter 时,奇怪的事情已经发生了! :P 我应该将进程的 inutstream 重定向到 inputstream 的子类,我需要有人帮助我,以便从 JTextField 而不是控制台获取输入。如果您有更简单的方法(无论如何都是听众?)给我一个提示.. :)
  • InputStream is = new ByteArrayInputStream(myTextField.getText().getBytes(Charset.forName("UTF-8"))); 有什么问题?

标签: java swing inputstream jtextfield


【解决方案1】:

我不明白为什么你需要一个扩展 InputStream 的 JTextField?基本上,您正在寻找的是:

  1. JTextField 上添加ActionListener(即,当使用按Enter 时,将调用actionPerformed
  2. 您需要使用getText() 获取JTextField 的text
  3. 然后您可以使用new ByteArrayInputStream(text.getBytes("UTF-8"));String text“转换”为InputStream

这是一个小sn-p,应该可以让您了解基本概念:

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 不是我要找的……除非我忽略了任何东西……
  • @Spiritios 拥有多个 ActionListener 不是问题。您拥有的 ActionListener 实际上也可能与我在回答中提到的相同。我几乎 99% 确信这是要走的路,所以你可能忽略了 ;-)。
  • 嗯好的...但是我使用的是Apache Commons PumpStreamHandler,基本上我需要一个InputStream,它将传递给构造函数以便由我调用的子进程使用,所以可以这样做真的使用听众吗?? :O
  • @Spiritios 我添加了一个示例代码,它可以让您了解如何进行。在动作监听器中,您可以调用您的 Apache commons pumpstreamhandler 等...
  • 这是对原始问题的更好答案。
【解决方案2】:

这个实现怎么样

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
 }

只有当我按回车时才读取?

当你调用in.read()时它会读取如果返回值-1它意味着流结束

(我是否可以进行修改以使 Enter 键清空 JTextField?)

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

【讨论】:

  • 是否容易修改,使InputStream外部设计为使用JTextField?更改代码非常令人沮丧,而且我的 JTextField 已经可以观察到其他一些东西,所以如果你可以稍微修改一下...... :)
  • 我不明白你的确切意思,但是,我对 InputStream 进行了一些更改以更稳定。
  • 现在这很简单,要检查一下,非常感谢您的帮助。顺便说一句,它只在我按 Enter 时读取吗? (我是否能够进行修改以使 Enter 键清空 JTextField?):D
  • 我已经更新了我的答案,但从未测试过。所以,如果它失败了,你不应该生我的气
  • 对于你的所有麻烦,我永远不会生你的气,我只能感谢你花了一段时间来帮助我! :)
猜你喜欢
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-16
  • 2012-03-03
  • 1970-01-01
  • 2014-11-03
相关资源
最近更新 更多