0

我一直在修改一个简单的 Java Swing 控制台,我决定为关键字添加一种突出显示的形式(通过为标记行旁边的区域着色)。当我通过搜索关键字“Exception”引发错误时,它可以正常工作,但是当我使用其中的关键字执行 System.out.println 时,它会突出显示所有内容。我认为该字符串以某种方式与所有已输入的字符串组合,这是导致此错误的原因,但我无法修复它。

这是一个屏幕截图:

在此处输入图像描述

不应突出显示文本“Hello World 2”和“Lets throw an error on this console”。

// Edited by Jeff B
// A simple Java Console for your application (Swing version)
// Requires Java 1.1.5 or higher
//
// Disclaimer the use of this source is at your own risk. 
//
// Permision to use and distribute into your own applications
//
// RJHM van den Bergh , rvdb@comweb.nl

import java.io.*;
import java.util.ArrayList;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class textAreaC extends JTextArea {
    int rowCount;
    int rowHeight;
    ArrayList<Point> exPoint = new ArrayList<Point>();

    public textAreaC() {
        rowHeight = this.getRowHeight();
    }

    public void paint(Graphics g) {
        super.paint(g);
        g.setColor(Color.red);
        for (int i = 0; i < exPoint.size(); i++) {
            g.fillRect(3, exPoint.get(i).x * rowHeight, 10, exPoint.get(i).y
                    * rowHeight);
        }
    }

    public void append(String str) {
        int rows = str.split("\r\n|\r|\n").length;
        if (str.contains("Exception")) {
            //System.out.println("This was the string: " + str + "It has " + rows + "rows" + " End String");
            exPoint.add(new Point(rowCount, rows));
        }
        rowCount += rows;
        super.append(str);

    }
}

public class Console extends WindowAdapter implements WindowListener,
        ActionListener, Runnable {
    private JFrame frame;
    private textAreaC textArea;
    private Thread reader;
    private Thread reader2;
    private boolean quit;

    private final PipedInputStream pin = new PipedInputStream();
    private final PipedInputStream pin2 = new PipedInputStream();

    Thread errorThrower; // just for testing (Throws an Exception at this Console

    public Console() {
        // create all components and add them
        frame = new JFrame("Java Console");
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        Dimension frameSize = new Dimension((int) (screenSize.width / 2),
                (int) (screenSize.height / 2));
        int x = (int) (frameSize.width / 2);
        int y = (int) (frameSize.height / 2);
        frame.setBounds(x, y, frameSize.width, frameSize.height);

        textArea = new textAreaC();
        textArea.setEditable(false);
        textArea.setMargin(new Insets(3, 20, 3, 3));
        JButton button = new JButton("clear");
        frame.getContentPane().setLayout(new BorderLayout());
        frame.getContentPane().add(new JScrollPane(textArea),
                BorderLayout.CENTER);
        frame.getContentPane().add(button, BorderLayout.SOUTH);
        frame.setVisible(true);
        frame.addWindowListener(this);
        button.addActionListener(this);

        try {
            PipedOutputStream pout = new PipedOutputStream(this.pin);
            System.setOut(new PrintStream(pout, true));
        } catch (java.io.IOException io) {
            textArea.append("Couldn't redirect STDOUT to this console\n"
                    + io.getMessage());
        } catch (SecurityException se) {
            textArea.append("Couldn't redirect STDOUT to this console\n"
                    + se.getMessage());
        }

        try {
            PipedOutputStream pout2 = new PipedOutputStream(this.pin2);
            System.setErr(new PrintStream(pout2, true));
        } catch (java.io.IOException io) {
            textArea.append("Couldn't redirect STDERR to this console\n"
                    + io.getMessage());
        } catch (SecurityException se) {
            textArea.append("Couldn't redirect STDERR to this console\n"
                    + se.getMessage());
        }

        quit = false; // signals the Threads that they should exit

        // Starting two seperate threads to read from the PipedInputStreams             
        //
        reader = new Thread(this);
        reader.setDaemon(true);
        reader.start();
        //
        reader2 = new Thread(this);
        reader2.setDaemon(true);
        reader2.start();

        // testing part
        // you may omit this part for your application
        // 
        //System.out.println("Test me please Exception\n testing 123");
        System.out.flush();
        System.out.println("Hello World 2");

        System.out.println("\nLets throw an error on this console");
        errorThrower = new Thread(this);
        errorThrower.setDaemon(true);
        errorThrower.start();
    }

    public synchronized void windowClosed(WindowEvent evt) {
        quit = true;
        this.notifyAll(); // stop all threads
        try {
            reader.join(1000);
            pin.close();
        } catch (Exception e) {
        }
        try {
            reader2.join(1000);
            pin2.close();
        } catch (Exception e) {
        }
        System.exit(0);
    }

    public synchronized void windowClosing(WindowEvent evt) {
        frame.setVisible(false); // default behaviour of JFrame 
        frame.dispose();
    }

    public synchronized void actionPerformed(ActionEvent evt) {
        textArea.setText("");
    }

    public synchronized void run() {
        try {
            while (Thread.currentThread() == reader) {
                try {
                    this.wait(100);
                } catch (InterruptedException ie) {
                }
                if (pin.available() != 0) {
                    String input = this.readLine(pin);
                    textArea.append(input);
                    //System.out.println(input.split("\r\n|\r|\n").length);
                }
                if (quit)
                    return;
            }

            while (Thread.currentThread() == reader2) {
                try {
                    this.wait(100);
                } catch (InterruptedException ie) {
                }
                if (pin2.available() != 0) {
                    String input = this.readLine(pin2);
                    textArea.append(input);
                }
                if (quit)
                    return;
            }
        } catch (Exception e) {
            textArea.append("\nConsole reports an Internal error.");
            textArea.append("The error is: " + e);
        }

        // just for testing (Throw a Nullpointer after 1 second)
        if (Thread.currentThread() == errorThrower) {
            try {
                this.wait(1000);
            } catch (InterruptedException ie) {
            }
            throw new NullPointerException(
                    "Application test: throwing an NullPointerException It should arrive at the console");
        }
    }

    public synchronized String readLine(PipedInputStream in) throws IOException {
        String input = "";
        do {
            int available = in.available();
            if (available == 0)
                break;
            byte b[] = new byte[available];
            in.read(b);
            input = input + new String(b, 0, b.length);
        } while (!input.endsWith("\n") && !input.endsWith("\r\n") && !quit);
        return input;
    }

    public static void main(String[] arg) {
        new Console(); // create console with not reference 
    }
}

我一直在做一些测试,看看这个打印输出: 在此处输入图像描述

要复制这一点,请在 reader(1) 中添加 System.out.prinln 语句并将输入附加到字符串的末尾。这就是我的prinlns的样子:

System.out.println("There should be a string before me.");
System.out.flush();
System.out.println("Test me please Exception");
System.out.flush();
System.out.println("Test print 2");
System.out.flush();
System.out.println("Test print 3");
System.out.flush();
System.out.println("Test me please Exception 2");
System.out.flush();
System.out.println("Exception here lololol");
System.out.flush();
System.out.println("Hello World 2");
System.out.flush();

我的读者看起来像这样:

if (pin.available()!=0)
    {

        String input=this.readLine(pin);
        System.out.println("this was printed by the thread second " + input);
        textArea.append(input);
        //System.out.println(input.split("\r\n|\r|\n").length);
    }
if (quit) return;

它将所有这些prinlns视为一个输入,这是java正在做的事情,还是我错过了什么?

4

1 回答 1

1

使用 HTML 进行输出,这更容易。就像第一个文本<html>一样(非常松散的 HTML)。或者设置内容类型。追加行,<br>依此类推。

它更灵活。


你做了两个多行字符串的附加。取行数将使字符串中的所有行变为红色。也许这个次优版本更像你想要的。

@Override
public void append(String str) {
    String[] lines = str.split("\r\n|\r|\n");
    int rows = lines.length;
    for (String line : lines) {
        super.append(line + "\n");
        if (line.contains("Exception")) {
            exPoint.add(new Point(rowCount, 1)); // 1 line
        }
        ++rowCount;
    }
}
于 2013-02-21T16:07:27.573 回答