将System.in重定向到Swing组件 [英] Redirect System.in to swing component

查看:49
本文介绍了将System.in重定向到Swing组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,我正在使用Swing和Apache Commons开发一个终端应用程序.我能够轻松地将 System.out System.err 重定向到 JTextArea ,但是如何为 System.in执行此操作?我是否需要重写 Inputstream 方法?我是否需要将 String JTextArea 转换为字节数组,然后将其传递给 InputStream ?代码示例会很好.

Hey guys I am making a terminal application using Swing and Apache Commons. I was able to redirect System.out and System.err to a JTextArea easily but how do I do that for System.in ? Will I need to override Inputstream methods? Do I need to convert the String from JTextArea to byte array and then pass it to InputStream? Code examples would be nice.

推荐答案

我最近尝试了相同的操作,这是我的代码:

I recently tried the same thing, here's my code:

class TexfFieldStreamer extends InputStream implements ActionListener {

    private JTextField tf;
    private String str = null;
    private int pos = 0;

    public TexfFieldStreamer(JTextField jtf) {
        tf = jtf;
    }

    //gets triggered everytime that "Enter" is pressed on the textfield
    @Override
    public void actionPerformed(ActionEvent e) {
        str = tf.getText() + "\n";
        pos = 0;
        tf.setText("");
        synchronized (this) {
            //maybe this should only notify() as multiple threads may
            //be waiting for input and they would now race for input
            this.notifyAll();
        }
    }

    @Override
    public int read() {
        //test if the available input has reached its end
        //and the EOS should be returned 
        if(str != null && pos == str.length()){
            str =null;
            //this is supposed to return -1 on "end of stream"
            //but I'm having a hard time locating the constant
            return java.io.StreamTokenizer.TT_EOF;
        }
        //no input available, block until more is available because that's
        //the behavior specified in the Javadocs
        while (str == null || pos >= str.length()) {
            try {
                //according to the docs read() should block until new input is available
                synchronized (this) {
                    this.wait();
                }
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        //read an additional character, return it and increment the index
        return str.charAt(pos++);
    }
}

并像这样使用它:

    JTextField tf = new JTextField();
    TextFieldStreamer ts = new TextFieldStreamer(tf);
    //maybe this next line should be done in the TextFieldStreamer ctor
    //but that would cause a "leak a this from the ctor" warning
    tf.addActionListener(ts);

    System.setIn(ts);

自从我编写Java以来​​已经有一段时间了,所以我可能不了解最新的模式.您可能还应该重载 int available(),但是我的示例仅包含最低限度的内容,以使其与 BufferedReader s readLine()一起使用功能.

Has been a while since I coded Java so I may not be up-to-date with the patterns. You should probably also overload int available() but my example just consists of the bare minimum to make it work with a BufferedReaders readLine() function.

为了使此代码适用于 JTextField ,您必须使用 implements KeyListener 而不是 implements ActionListener 然后在您的TextArea上使用 addKeyListener(...).您需要的而不是 actionPerformed(...)的函数是 public void keyPressed(KeyEvent e),然后您必须测试 if(e.getKeyCode()== e.VK_ENTER),而不是使用整个文本,您只需使用

For this to work for a JTextField you have to use implements KeyListener instead of implements ActionListener and then use addKeyListener(...) on your TextArea. The function that you need instead of actionPerformed(...) is public void keyPressed(KeyEvent e) and then you have to test for if (e.getKeyCode() == e.VK_ENTER) and instead of using the whole text you just use a substring from the last line before the cursor with

//ignores the special case of an empty line
//so a test for \n before the Caret or the Caret still being at 0 is necessary
int endpos = tf.getCaret().getMark();
int startpos = tf.getText().substring(0, endpos-1).lastIndexOf('\n')+1;

输入字符串的

.因为否则,每次您按Enter键时,您都将读取整个TextArea.

for the input string. Because otherwise you would read the whole TextArea every time you press enter.

这篇关于将System.in重定向到Swing组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆