Replicating console functionality with a ListView

后端 未结 1 992
花落未央
花落未央 2021-01-15 03:54

I apologize for not being able to think of a more descriptive title.

I have managed to redirect the system.out to a new ListView via my own OutputStream class

1条回答
  •  小鲜肉
    小鲜肉 (楼主)
    2021-01-15 04:31

    Since you are looking for behavior that corresponds to a system or IDE console, that corresponds, in part, to splitting the output into logical units (i.e. "lines") at newline characters. That would happen automatically if you just collected whatever is written and appended it to a text area, so I would encourage you to try that and see. Even if it turns out to be less efficient, it may still be plenty efficient for your purposes.

    If you want to proceed with the ListView, however, then your Console class needs to internally buffer the data written to it, scan for newlines, and break up the output into cells at newlines. It create a new cell only when it sees a newline, and in that case include all the buffered text up to, but not including that newline.


    Update:

    A ByteArrayOutputStream would make a fine buffer. Something like this, for example:

    public class Console extends OutputStream {
    
        private ListView output;
    
        private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    
        public Console(ListView output)  {
            this.output = output;
        }
    
        private void addText() throws IOException {
            String text = buffer.toString("UTF-8");
            buffer.reset();
            Platform.runLater( () -> output.getItems().add(text) );
        }
    
        @Override
        public void write(int b) throws IOException {
            if (b == '\n') {
                addText();
            } else {
                buffer.write(b);
            }
        }
    
        @Override
        public void write(byte[] b, int off, int len) throws IOException {
            int bound = off + len;
            for (int i = off; i < bound; i++) {
                if (b[i] == '\n') {
                    buffer.write(b, off, i - off);
                    addText();
                    off = i + 1;
                }
            }
            assert(off <= bound);
            buffer.write(b, off, bound - off);
        }
    
        @Override
        public void write(byte[] b) throws IOException {
            write(b, 0, b.length);
        }
    
        @Override
        public void flush() throws IOException {
            // outputs all currently buffered data as a new cell, without receiving
            // a newline as otherwise is required for that
            addText();
        }
    
        @Override
        public void close() throws IOException {
            flush();
            buffer.close();
        }
    }
    

    0 讨论(0)
提交回复
热议问题