将命令行文本输出到 Javafx Textarea

Posted

技术标签:

【中文标题】将命令行文本输出到 Javafx Textarea【英文标题】:Outputing command line text to Javafx Text Area 【发布时间】:2020-10-12 23:50:56 【问题描述】:

我正在尝试设置它,以便命令行输出转到我的 GUI 的 Javafx TextArea,使用以下代码将命令行输出附加到 TextArea:

import javafx.scene.control.TextArea;

import javax.swing.*;
import java.io.OutputStream;

public class CustomOutputStream extends OutputStream 
    private static TextArea textArea = new TextArea();
    public CustomOutputStream(TextArea textArea) 
        this.textArea = textArea;
    

    @Override
    public void write(int b)
        textArea.appendText(String.valueOf((char)b));

    

 PrintStream printStream = new PrintStream(new CustomOutputStream(textArea));
        System.setOut(printStream);

但这似乎会导致 GUI 停止响应,并给出以下越界错误:

Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 3
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:248)
at java.base/java.util.Objects.checkIndex(Objects.java:373)
at java.base/java.util.ArrayList.get(ArrayList.java:426)
at javafx.base/com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
at javafx.base/com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:306)
at javafx.graphics/javafx.scene.Parent.updateCachedBounds(Parent.java:1704)
at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1648)
at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1501)
at javafx.graphics/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:115)
at javafx.graphics/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:84)
at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBoundsImpl(RegionHelper.java:78)
at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBounds(RegionHelper.java:62)
at javafx.graphics/javafx.scene.layout.Region.doComputeGeomBounds(Region.java:3289)
at javafx.graphics/javafx.scene.layout.Region$1.doComputeGeomBounds(Region.java:168)
at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.computeGeomBoundsImpl(RegionHelper.java:89)
at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:115)
at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3843)
at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3805)
at javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3753)
at javafx.graphics/javafx.scene.Node.intersectsBounds(Node.java:5288)
at javafx.graphics/javafx.scene.Node$1.intersectsBounds(Node.java:549)
at javafx.graphics/com.sun.javafx.scene.NodeHelper.intersectsBounds(NodeHelper.java:262)
at javafx.graphics/javafx.scene.layout.Region.doPickNodeLocal(Region.java:3158)
at javafx.graphics/javafx.scene.layout.Region$1.doPickNodeLocal(Region.java:184)
at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.pickNodeLocalImpl(RegionHelper.java:104)
at javafx.graphics/com.sun.javafx.scene.NodeHelper.pickNodeLocal(NodeHelper.java:128)
at javafx.graphics/javafx.scene.Node.pickNode(Node.java:5198)
at javafx.graphics/javafx.scene.Scene$MouseHandler.pickNode(Scene.java:4033)
at javafx.graphics/javafx.scene.Scene.pick(Scene.java:2065)
at javafx.graphics/javafx.scene.Scene$MouseHandler.process(Scene.java:3843)
at javafx.graphics/javafx.scene.Scene.processMouseEvent(Scene.java:1885)
at javafx.graphics/javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2618)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:409)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:299)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:447)
at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:412)
at javafx.graphics/com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:446)
at javafx.graphics/com.sun.glass.ui.View.handleMouseEvent(View.java:556)
at javafx.graphics/com.sun.glass.ui.View.notifyMouse(View.java:942)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:832)

【问题讨论】:

这个@Override public void write(int b) textArea.appendText(String.valueOf((char)b)); 看起来不正确。我认为int b 应该是某种KeyEvent minimal reproducible example 请.. 【参考方案1】:

这是一个将 TextArea 转换为控制台输出的可运行示例。我没有看到任何重大差异,我会删除 import javax.swing.*; 并查看它需要哪些导入

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.io.OutputStream;
import java.io.PrintStream;


public class MainNoFXML extends Application 

    @Override
    public void start(Stage stage) throws Exception 
        TextArea textArea = new TextArea();

        System.setOut(new PrintStream(new CustomOutputStream(textArea)));

        VBox vBox = new VBox(textArea);
        vBox.setAlignment(Pos.CENTER);


        stage  = new Stage();
        stage.setScene(new Scene(vBox));
        stage.show();

        System.out.println("Test Console Print to TextArea");
    

    public class CustomOutputStream extends OutputStream 
        private TextArea textArea;
        public CustomOutputStream(TextArea textArea) 
            this.textArea = textArea;
        

        @Override
        public void write(int b)
            textArea.appendText(String.valueOf((char)b));

        
    


【讨论】:

以上是关于将命令行文本输出到 Javafx Textarea的主要内容,如果未能解决你的问题,请参考以下文章

如何将 Cmder 设置为不换行文本输出

将 SLF4J 日志重定向到 JavaFX 中的 TextArea

将 System.out 重定向到 JavaFX 中的 TextArea

将电话号码从 Outlook 粘贴到 JavaFX TextField 或 TextArea 会产生无关字符

如何知道用户在 JavaFX TextArea 中选择了哪个文本字符串

如何在 setText 之后滚动 JavaFX TextArea