2017-01-10 1 views
0

여기 내 문제입니다. 내가 다음 코드를 사용하는 경우 :자바 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)); 

그래서 같이 표시됩니다 : 나는 내 자신의 main 방법에서 코드를 실행하는 방법을 내가 잊고 있었던

enter image description here

가 배치, 당신이 당신의 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); 

null로 설정하십시오.

JScrollPane scrollPane = new JScrollPane(textArea); 
scrollPane.setBorder(null); 
frame.getContentPane().add(scrollPane, BorderLayout.CENTER); 

또 다른 문제 :이 스레드 안전 스윙되지 않은 : 당신은 스윙 이벤트 스레드 떨어져 textArea.append(...) 호출을하고

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

} 

을,이 간헐적 디버깅하기 어려운 될 수 있습니다 던져 질 예외. 이 텍스트 구성 요소에 ()에만 이벤트 발송 스레드를 추가하십시오.

+0

글쎄요! 공장. 어떤 사람들은 짠다고 말한 것에 대해 유감스럽게 생각합니다. 아주 나쁜 날. 감사합니다 이것이 문제를 해결했습니다! –

+0

당신은 내가 깨닫는 것보다 빠르다. 1+ – Frakcool

+0

@Frakcool : 1+도 대답했다. –