这是我的问题。 当我使用以下代码时:
package xyz.lexium.giapb.ui;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class ConsoleWindow extends WindowAdapter implements WindowListener, ActionListener, Runnable {
private JFrame frame;
private JTextArea textArea;
private Thread reader;
private Thread reader2;
private boolean quit;
private final PipedInputStream pin = new PipedInputStream();
private final PipedInputStream pin2 = new PipedInputStream();
public ConsoleWindow() {
frame = new JFrame("GIAPB - Console");
Dimension dimension = Toolkit.getDefaultToolkit().getScreenSize();
int x = (int) ((dimension.getWidth() - frame.getWidth()) / 3);
int y = (int) ((dimension.getHeight() - frame.getHeight()) / 3);
frame.setSize(x, y);
textArea = new JTextArea();
textArea.setEditable(false);
JButton button = new JButton("clear");
button.setBorder(null);
button.setBackground(Color.BLACK);
button.setForeground(Color.white);
frame.getContentPane().setBackground(Color.BLACK);
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(new JScrollPane(textArea), BorderLayout.CENTER);
frame.getContentPane().add(button, BorderLayout.SOUTH);
frame.addWindowListener(this);
textArea.setBackground(Color.BLACK);
textArea.setForeground(Color.white);
textArea.setBorder(null);
frame.setVisible(true);
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();
}
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);
}
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);
}
}
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;
}
}
它创建了我的控制台,但在文本区域和边框之间添加了一条白线。我该如何删除
答案 0 :(得分:1)
您忘记了JScrollPane有边框。
frame.getContentPane().add(new JScrollPane(textArea), BorderLayout.CENTER);
将其设为null。
JScrollPane scrollPane = new JScrollPane(textArea);
scrollPane.setBorder(null);
frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
另一个问题:这不是Swing线程安全的:
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); // **************
}
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); // **************
}
}
你正在从Swing事件线程调用textArea.append(...)
调用,这可能导致很难调试间歇性异常。请务必仅将此文本组件附加到事件派发线程。
答案 1 :(得分:1)
问题是因为JScrollPane
也有边框。
在这种情况下,您可以使用以下命令将其删除:
JScrollPane scroll = new JScrollPane(textArea);
scroll.setBorder(null);
将JScrollPane
添加到您的框架中:
frame.getContentPane().add(textArea, BorderLayout.CENTER);
但是这将删除按钮和文本区域之间的边框
因此,您需要在MatteBorder
:
JButton
button.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.white));
所以它看起来像这样:
我忘了在我自己的main
方法中放置代码的方式,因为您忘记将其添加为MCVE的一部分:
它会将程序放在Event Dispatch Thread (EDT)
上public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new ConsoleWindow();
}
});
}