我一直在修改一个简单的Java Swing控制台,我决定为关键字添加一种突出显示形式(通过着色标记线旁边的区域)。我通过搜索关键字“Exception”来抛出错误时工作正常,但是当我在其中使用关键字执行System.out.println时,它会突出显示所有内容。我认为字符串以某种方式与已输入的所有字符串组合,这是导致此错误的原因,但我无法修复它。
以下是截图:
不应突出显示“Hello World 2”和“Lets在此控制台上抛出错误”文本。
// 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语句,并将输入附加到字符串的末尾。这就是我的公主的样子:
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;
它将所有这些原则视为单一输入,这是java正在做的事情,还是我错过了什么?
答案 0 :(得分: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;
}
}