2013-12-14 63 views
0

任何人都可以告訴我爲什麼TryGraphic用第一個main()掃描儀凍結JFrame?如果我刪除了Scanner或者直接執行代碼,所有的作品。 (原「嘗試」類明明做了很多不同的東西,我寫了這些類,使之簡單。)JFrame凍結與不同的System.in

import java.util.Scanner; 


public class Try { 

    public Try(){ 

    } 

    public static void main(String[] args){ 
     System.out.println("FOO"); 
     String s = new Scanner(System.in).nextLine(); 
     System.out.println(s); 
    } 
} 

這是圖形執行:

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.IOException; 
import java.io.PipedInputStream; 
import java.io.PipedOutputStream; 
import java.io.PrintStream; 
import java.io.PrintWriter; 
import java.util.Scanner; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.JTextField; 
import javax.swing.SwingWorker; 


public class TryGraphic extends JFrame{ 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 7491282237007954227L; 



    private JButton execute = new JButton("Esegui"); 

    private PipedInputStream inPipe = new PipedInputStream(); 
    private PipedInputStream outPipe = new PipedInputStream(); 
    private JTextField tfIn = new JTextField(); 
    private JTextArea outputArea = new JTextArea(); 

    private PrintWriter inWriter; 


    public TryGraphic(){ 
     super("TRY"); 

     System.setIn(inPipe); 

     try { 
      System.setOut(new PrintStream(new PipedOutputStream(outPipe), true)); 
      inWriter = new PrintWriter(new PipedOutputStream(inPipe), true); 
     }catch (IOException ioe){ 
      ioe.printStackTrace(); 
     }    

     tfIn.addActionListener(new ActionListener(){ 
      @Override 
      public void actionPerformed(ActionEvent event){ 
        String text = tfIn.getText(); 
        tfIn.setText(""); 
        inWriter.println(text); 
      } 
     }); 

     this.add(execute,BorderLayout.SOUTH); 
     this.add(new JScrollPane(outputArea),BorderLayout.CENTER); 
     this.add(tfIn, BorderLayout.NORTH); 

     execute.addActionListener(new ActionListener(){ 

      @Override 
      public void actionPerformed(ActionEvent e) { 

       SwingWorker<Void,String> worker = new SwingWorker<Void, String>() { 
        protected Void doInBackground() throws Exception { 
         Scanner s = new Scanner(outPipe); 
         while (s.hasNextLine()) { 
           String line = s.nextLine(); 
           publish(line); 

         } 
         return null; 
        } 

        @Override 
        protected void process(java.util.List<String> chunks) { 
         for (String line : chunks){ 
          outputArea.append(line+System.lineSeparator()); 
          outputArea.validate(); 
          } 

        } 
       }; 

       worker.execute(); 

       Try.main(new String[]{""}); 
      } 

     }); 

     this.setSize(300,300); 
     this.setVisible(true); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


    } 



    public static void main(String[] args){ 
     new TryGraphic(); 
    } 
} 

回答

1

你擋住了GUI事件調度線程。您需要生成一個單獨的線程來等待輸入,以便您可以保持GUI的響應。

通過創建一個SwingWorker來處理您的TryGraphic類中的I/O,您已經在做正確的事情。您應該執行類似的操作,將Try.main(new String[]{""});呼叫從Event Dispatch Thread中移出,這將使您的JFrame不會鎖定。

+0

我知道EDT是阻塞的,但我不知道如何將'Try.main(String [] args)'從'actionPerformed'移出。我是否需要爲每個功能創建單獨的線程? – Stereo89

+0

@ Stereo89 - 您需要將任何潛在的阻塞計算移出EDT。爲什麼你在讀取GUI應用程序中的'System.in'時無法阻止?如果你通過GUI獲得輸入,你可以完全避免這種情況。 – DaoWen

+0

我需要擴展一個已經完成「東西」的存在類,比如請求'String name',這樣我就不能在GUI中移動請求。當'main()'請求輸入時,我需要詢問輸入。但你可以幫助我「移動」的含義嗎?我需要創建一個新的Thread(),一個新的SwingWorker()'?奇怪的是,如果我直接執行代碼而沒有啓動執行的'JButton',一切正常。我知道問題是'actionPerformed'('JButton execute'),因爲它需要另一個'actionPerformed'('JTextField tfIn'),但我不知道如何解決。 – Stereo89