使用ListView

时间:2018-02-02 19:12:16

标签: java javafx

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

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

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);
}

}

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

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

这是我使用事件处理程序测试输出的地方,该事件处理程序打印鼠标悬停在其上的图块坐标:

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()。这是输出:

system.out.print

如果我使用println()

system.out.println

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

1 个答案:

答案 0 :(得分:3)

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

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

<强>更新

ByteArrayOutputStream会产生一个很好的缓冲区。像这样的东西,例如:

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();
    }
}