使用ListView复制控制台功能 [英] Replicating console functionality with a ListView

查看:102
本文介绍了使用ListView复制控制台功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我为无法想到更具描述性的标题而道歉。

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

我设法通过我自己的OutputStream类将system.out重定向到一个新的ListView Console

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

public class Console extends OutputStream {

private ListView<String> output;

public Console(ListView<String> output)  {
    this.output = output;
}

private void addText(String str) {
    Platform.runLater( () -> output.getItems().add(str) );
}

@Override
public void write(int b) throws IOException {
    addText(String.valueOf((char) b));      
}

@Override
public void write(byte[] b, int off, int len) throws IOException {
    addText(new String(b, off, len));
}

@Override
public void write(byte[] b) throws IOException {
    write(b, 0, b.length);
}

}

在这里,我创建控制台我的控制器类。 输出是我的FXML中
ListView的名称:

Here, I create the console in my controller class. output is the name of the ListView in my FXML:

private void buildConsole() {
    Console console = new Console(output);
    PrintStream ps = new PrintStream(console, true);
    System.setOut(ps);
    System.setErr(ps);
}

这是我用输出打印瓷砖的事件处理程序测试输出的地方鼠标悬停的坐标:

Here is where I am testing the output with an event handler that prints the tile coordinates over which my mouse is hovering:

tile.setOnMouseEntered(e -> {
   tile.setFill(hoverColor);
   showConnections(tile);
   gridController.getCoordinateLabel().setText(tile.getVertex().toString());
        System.out.print("Tile " + tile.getVertex().toString() + " selected.");
    });

请注意我使用的是 System.out.print()而不是 println()。这是输出:

Notice that I am using System.out.print() and not println(). This is the output:

如果我使用 println()

我理想的行为是:
system.out.print() - 要添加到同一文本中的文本线。
system.out.println() - 文本已添加到下一个单元格。

My ideal behavior is: system.out.print() - text to be added to the same line. system.out.println() - text added to the next cell.

推荐答案

由于您正在寻找与系统或IDE控制台相对应的行为,因此部分地对应于在换行符处将输出拆分为逻辑单元(即行)。如果您只是收集了所写的内容并将其附加到文本区域,这将自动发生,因此我鼓励您尝试并查看。即使结果效率较低,它仍然可以为您的目的提供足够的效率。

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.

如果您想继续使用ListView,那么您的控制台类需要在内部缓冲写入的数据,扫描换行符,并将输出分解为换行符中的单元格。它会在看到换行符时创建一个新的 单元格,在这种情况下包括所有缓冲的文本,但不包括该换行符。

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.

更新

A ByteArrayOutputStream 会做一个很好的缓冲区。这样的事情,例如:

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

public class Console extends OutputStream {

    private ListView<String> output;

    private ByteArrayOutputStream buffer = new ByteArrayOutputStream();

    public Console(ListView<String> 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();
    }
}

这篇关于使用ListView复制控制台功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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