Java 使用ListView复制控制台功能
很抱歉,我想不出更具描述性的标题 我已通过自己的OutputStream类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
控制台将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;i assert(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();
}
}