java JFrame中奇怪的空白区域

这是我的问题。 当我使用以下代码时:

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; } } 

它使我的控制台,但在文本区域和边框之间添加了一条白线。 我该如何删除它

问题是因为JScrollPane也有边框。

在这种情况下,您可以删除它:

 JScrollPane scroll = new JScrollPane(textArea); scroll.setBorder(null); 

并将JScrollPane添加到您的框架中:

 frame.getContentPane().add(textArea, BorderLayout.CENTER); 

但这将删除按钮和文本区域之间的边框

所以你需要在JButton的顶部创建一个MatteBorder

 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(); } }); } 

您忘记了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(...) ,这可能导致难以调试抛出的间歇性exception。 请务必仅在事件派发线程附加到此文本组件。