如何在java中将文本区域转换为输入流? 我试图在我的一本书中制作一些C++代码的java端口,并且该书使用一些特定于OS的东西来在控制台窗口中着色文本。

如何在java中将文本区域转换为输入流? 我试图在我的一本书中制作一些C++代码的java端口,并且该书使用一些特定于OS的东西来在控制台窗口中着色文本。,java,swing,io,console,jtextpane,Java,Swing,Io,Console,Jtextpane,我决定,因为没有简单的方法可以让它在java中跨平台工作,所以我可以创建一个带有文本区域的窗口来模拟控制台。打印和着色文本很简单,但我不知道如何让控制台的输入流部分工作 我希望Console.getIn()方法返回的对象与System.in完全相同。我当前的代码可以正常工作,但如果用作扫描仪的输入,则会挂起。我在下面列出了我的实现,请告诉我您是否可以告诉我我的代码出了什么问题,或者是否有更好的方法来做到这一点 import java.awt.Color; import java.awt.Dime

我决定,因为没有简单的方法可以让它在java中跨平台工作,所以我可以创建一个带有文本区域的窗口来模拟控制台。打印和着色文本很简单,但我不知道如何让控制台的输入流部分工作

我希望Console.getIn()方法返回的对象与System.in完全相同。我当前的代码可以正常工作,但如果用作扫描仪的输入,则会挂起。我在下面列出了我的实现,请告诉我您是否可以告诉我我的代码出了什么问题,或者是否有更好的方法来做到这一点

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

/**
 *
 * @author William Matrix Peckham
 */
public class Console extends JTextPane {

    DocOutputStream out;
    PrintStream pout;
    DocInputStream in;
    JFrame frame;
    StyledDocument doc;



    public Console() {
        super();
        setPreferredSize(new Dimension(500, 500));
        doc = this.getStyledDocument();
        out = new DocOutputStream(doc,this);
        pout=new PrintStream(out);
        in = new DocInputStream();
        this.addKeyListener(in);
        setFGColor(Color.black);
        setBGColor(Color.white);
        frame = new JFrame("Console");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new JScrollPane(this));
        frame.pack();
        frame.setVisible(true);
    }

    public InputStream getIn(){
        return in;
    }
    public PrintStream getOut(){
        return pout;
    }

    public void setFGColor(Color c){
        StyleConstants.setForeground(out.cur, c);
    }
    public void setBGColor(Color c){
        StyleConstants.setBackground(out.cur, c);
    }

    private static class DocOutputStream extends OutputStream {

        StyledDocument doc;
        MutableAttributeSet cur;
        JTextPane pane;

        public DocOutputStream(StyledDocument doc, JTextPane pane) {
            this.doc = doc;
            this.pane=pane;
            cur=new SimpleAttributeSet();
        }

        @Override
        public void write(int b) throws IOException {
            try {
                doc.insertString(doc.getLength(), (char)b+"", cur);
                pane.setCaretPosition(doc.getLength());
            } catch (BadLocationException ex) {
                Logger.getLogger(Console.class.getName()).
                        log(Level.SEVERE, null, ex);
            }

        }
    }

    private static class DocInputStream extends InputStream implements KeyListener {

        ArrayBlockingQueue<Integer> queue;

        public DocInputStream(){
            queue=new ArrayBlockingQueue<Integer>(1024);
        }

        @Override
        public int read() throws IOException {
            Integer i=null;
            try {
                i = queue.take();
            } catch (InterruptedException ex) {
                Logger.getLogger(Console.class.getName()).
                        log(Level.SEVERE, null, ex);
            }
            if(i!=null)
                return i;
            return -1;
        }

        @Override
        public void keyTyped(KeyEvent e) {
        }

        @Override
        public void keyPressed(KeyEvent e) {

        }

        @Override
        public void keyReleased(KeyEvent e) {
            int c = e.getKeyCode();
            try {
                queue.put(c);
            } catch (InterruptedException ex) {
                Logger.getLogger(Console.class.getName()).
                        log(Level.SEVERE, null, ex);
            }
        }

    }
}
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.event.KeyEvent;
导入java.awt.event.KeyListener;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.OutputStream;
导入java.io.PrintStream;
导入java.util.concurrent.ArrayBlockingQueue;
导入java.util.logging.Level;
导入java.util.logging.Logger;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JTextPane;
导入javax.swing.text.AttributeSet;
导入javax.swing.text.BadLocationException;
导入javax.swing.text.DefaultStyledDocument;
导入javax.swing.text.MutableAttributeSet;
导入javax.swing.text.SimpleAttributeSet;
导入javax.swing.text.StyleConstants;
导入javax.swing.text.StyleContext;
导入javax.swing.text.StyledDocument;
/**
*
*@William Matrix Peckham作者
*/
公共类控制台扩展了JTextPane{
DocOutputStreamOut;
撅嘴;
文档输入流输入;
JFrame框架;
样式文件;
公共控制台(){
超级();
setPreferredSize(新尺寸(500500));
doc=this.getStyledDocument();
out=新的DocOutputStream(doc,this);
pout=新打印流(输出);
in=新的DocInputStream();
this.addKeyListener(in);
setFGColor(Color.black);
setBGColor(颜色:白色);
框架=新的JFrame(“控制台”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(新的JScrollPane(this));
frame.pack();
frame.setVisible(true);
}
公共输入流getIn(){
返回;
}
公共PrintStream getOut(){
回撅嘴;
}
公共void setFGColor(颜色c){
setForeground(out.cur,c);
}
公共区域颜色(c色){
StyleConstants.setBackground(out.cur,c);
}
私有静态类DocOutputStream扩展了OutputStream{
样式文件;
可变属性集cur;
JTextPane窗格;
公共文档输出流(StyledDocument文档,JTextPane窗格){
this.doc=doc;
this.pane=pane;
cur=新的SimpleAttributeSet();
}
@凌驾
公共无效写入(int b)引发IOException{
试一试{
doc.insertString(doc.getLength(),(char)b+“”,cur);
setCaretPosition(doc.getLength());
}捕获(BadLocationException ex){
Logger.getLogger(Console.class.getName())。
日志(Level.SEVERE、null、ex);
}
}
}
私有静态类DocInputStream扩展InputStream实现KeyListener{
ArrayBlockingQueue;
公共DocInputStream(){
队列=新的ArrayBlockingQueue(1024);
}
@凌驾
public int read()引发IOException{
整数i=null;
试一试{
i=queue.take();
}捕获(中断异常例外){
Logger.getLogger(Console.class.getName())。
日志(Level.SEVERE、null、ex);
}
如果(i!=null)
返回i;
返回-1;
}
@凌驾
public void keyTyped(KeyEvent e){
}
@凌驾
按下公共无效键(按键事件e){
}
@凌驾
公共无效密钥已释放(密钥事件e){
int c=e.getKeyCode();
试一试{
队列。put(c);
}捕获(中断异常例外){
Logger.getLogger(Console.class.getName())。
日志(Level.SEVERE、null、ex);
}
}
}
}

编辑:请注意,在read()中,我尝试了poll()而不是take(),这使它完全停止了阻塞,但我认为这可能会使Scanner永远停止阻塞,这是正确的,但它也会使它完全停止获取任何实际输入。

也许该方法可以满足您的要求。您可以使用JTextArea或JTextPane作为控制台组件。

我知道了。问题是扫描器调用了InputStream.read(char[],int,int),它被实现为读取整个流或整个大小的缓冲区。扫描程序试图填充8000+字节的缓冲区,默认的读取(…)实现仅在缓冲区已满或-1已读取(EOF)后才停止调用read()

这会导致扫描仪永远阻塞,因为大多数控制台输入永远不会那么长。解决方案是覆盖缓冲读取。我需要的版本将阻止第一个字节,并在没有更多字符时返回,我认为BufferedInputStream已经通过调用流上的available()实现了这一点,所以我尝试在重写available之后将类包装成一个,但这不起作用。我的新实现使用available()和EOF作为停止案例

这就是实现现在的样子:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

/**
 *
 * @author William Matrix Peckham
 */
public class Console extends JTextPane {

    DocOutputStream out;
    PrintStream pout;
    DocInputStream in;
    JFrame frame;
    StyledDocument doc;



    public Console() {
        super();
        setPreferredSize(new Dimension(500, 500));
        doc = this.getStyledDocument();
        out = new DocOutputStream(doc,this);
        pout=new PrintStream(out);
        in = new DocInputStream();
        this.addKeyListener(in);
        setFGColor(Color.black);
        setBGColor(Color.white);
        frame = new JFrame("Console");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new JScrollPane(this));
        frame.pack();
        frame.setVisible(true);
    }

    public InputStream getIn(){
        return in;
    }
    public PrintStream getOut(){
        return pout;
    }

    public void setFGColor(Color c){
        StyleConstants.setForeground(out.cur, c);
    }
    public void setBGColor(Color c){
        StyleConstants.setBackground(out.cur, c);
    }

    private static class DocOutputStream extends OutputStream {

        StyledDocument doc;
        MutableAttributeSet cur;
        JTextPane pane;

        public DocOutputStream(StyledDocument doc, JTextPane pane) {
            this.doc = doc;
            this.pane=pane;
            cur=new SimpleAttributeSet();
        }

        @Override
        public void write(int b) throws IOException {
            try {
                doc.insertString(doc.getLength(), (char)b+"", cur);
                pane.setCaretPosition(doc.getLength());
            } catch (BadLocationException ex) {
                Logger.getLogger(Console.class.getName()).
                        log(Level.SEVERE, null, ex);
            }

        }
    }

    private static class DocInputStream extends InputStream implements KeyListener {

        ArrayBlockingQueue<Integer> queue;

        public DocInputStream(){
            queue=new ArrayBlockingQueue<Integer>(1024);
        }

        @Override
        public int read() throws IOException {
            Integer i=null;
            try {
                i = queue.take();
            } catch (InterruptedException ex) {
                Logger.getLogger(Console.class.getName()).
                        log(Level.SEVERE, null, ex);
            }
            if(i!=null)
                return i;
            return -1;
        }

        @Override
        public int read(byte[] b, int off, int len) throws IOException {
            if (b == null) {
                throw new NullPointerException();
            } else if (off < 0 || len < 0 || len > b.length - off) {
                throw new IndexOutOfBoundsException();
            } else if (len == 0) {
                return 0;
            }
                    int c = read();
            if (c == -1) {
                return -1;
            }
            b[off] = (byte)c;

            int i = 1;
            try {
                for (; i < len && available() > 0 ; i++) {
                    c = read();
                    if (c == -1) {
                        break;
                    }
                    b[off + i] = (byte)c;
                }
            } catch (IOException ee) {
            }   
            return i;

        }



        @Override
        public int available(){
            return queue.size();
        }

        @Override
        public void keyTyped(KeyEvent e) {
            int c = e.getKeyChar();
            try {
                queue.put(c);
            } catch (InterruptedException ex) {
                Logger.getLogger(Console.class.getName()).
                        log(Level.SEVERE, null, ex);
            }
        }

        @Override
        public void keyPressed(KeyEvent e) {

        }

        @Override
        public void keyReleased(KeyEvent e) {
        }

    }
}
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.event.KeyEvent;
导入java.awt.event.KeyListener;
导入java.io.BufferedInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.OutputStream;
导入java.io.PrintStream;
感应电动机