Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用ListView复制控制台功能_Java_Javafx - Fatal编程技术网

Java 使用ListView复制控制台功能

Java 使用ListView复制控制台功能,java,javafx,Java,Javafx,很抱歉,我想不出更具描述性的标题 我已通过自己的OutputStream类控制台将system.out重定向到新的ListView: public class Console extends OutputStream { private ListView<String> output; public Console(ListView<String> output) { this.output = output; } private void addText

很抱歉,我想不出更具描述性的标题

我已通过自己的OutputStream类
控制台将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);
}

}
这里是我使用事件处理程序测试输出的地方,该事件处理程序打印鼠标悬停的平铺坐标:

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

如果我要使用
println()

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

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

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


更新

一个
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();
    }
}
公共类控制台扩展OutputStream{
私有列表视图输出;
private ByteArrayOutputStream buffer=new ByteArrayOutputStream();
公共控制台(ListView输出){
这个。输出=输出;
}
私有void addText()引发IOException{
字符串文本=buffer.toString(“UTF-8”);
reset();
Platform.runLater(()->output.getItems().add(text));
}
@凌驾
公共无效写入(int b)引发IOException{
如果(b=='\n'){
addText();
}否则{
缓冲区。写入(b);
}
}
@凌驾
公共无效写入(字节[]b,int off,int len)引发IOException{
int-bound=off+len;
for(int i=off;iassert(off)为什么最终用户会调用这两种方法中的哪一种?我认为您描述的内容不太一致。您的输出流为
write()的每次调用创建一个新单元是没有意义的
method。那么在换行符处拆分单元格呢?我想我没有正确描述我正在寻找的功能-让我进行编辑。如果我使用
system.out.print()
,我希望将文本添加到同一行。如果我使用
system.out.println()
,我希望文本添加到下一个单元格。@DylanRussell,这确实不同,但仍然没有意义。
PrintStream.println()
的用户通常希望他打印的内容从当前行(即单元格)开始,但接下来打印的内容将转到新行(单元格)但是,你还需要考虑正确的解释应该是一个文字新行被写。我明白。我只是在寻找你在IDE控制台中期待的完全相同的功能。我使用的是ListVIEW,因为我理解这比文本区域更有效。谢谢你的回答,我会的。研究在我的
控制台
类中添加缓冲区函数。您的代码非常有用。只是一个问题:即使没有换行符,我也会将控制台输出拆分到不同的行上。我正在尝试使用偏移量和长度来修改写入方法,但没有任何效果。有关如何修复此行为的任何提示?谢谢。是吗你的意思是条件为
b[i]='\n'
?将索引与换行常量进行比较没有多大意义……是吗?是的,这就是问题所在。谢谢你回答这里和我的新问题。
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();
    }
}