2017-01-10 64 views
0

这是我的问题。 当我使用下面的代码: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; 
} 
} 

这让我的控制台,但增加了文本区边界之间的白线。我如何删除这个

+1

让我们看看你的[mcve]。 –

+0

那么,你想把文字放在底部?请提供一个有效的[mcve] – Frakcool

+0

很难在图片中看到,但在文本的右侧有一个白色条,用于区分文本区域和边框。我如何摆脱这个边界? –

回答

1

问题是因为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)); 

因此,这将是这样的:

enter image description here

我忘了把我怎么跑我自己的main方法你的代码,因为你忘了将其添加为您MCVE的一部分:

它将把程序上Event Dispatch Thread (EDT)

public static void main(String[] args) { 
    SwingUtilities.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
      new ConsoleWindow(); 
     } 
    }); 
} 
1

你忘了JScrollPane有一个边框。

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

将其设置为空。

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); // ************** 
    } 

} 

你让textArea.append(...)接听Swing事件线程的,这可能会导致难以调试间歇抛出异常。请务必在的事件分派线程上追加此文本组件

+0

好吧,看看那个!作品。对不起,有人说......咸。非常糟糕的一天。谢谢,这确实解决了这个问题! –

+0

你比我快,注意到它,1+ – Frakcool

+0

@Frakcool:1+以及你的答案。 –