2016-12-29 68 views
0

我在做一個簡單的java編譯器。我的程序正在運行,但如果它要掃描,它將不會接收輸入並且會凍結。做Java編譯器時不要輸入

從我的編譯器的一個小代碼

public class ProcessBuilderMultipleCommandsExample { 
    static String backSlashFl = "C:\\Users\\xxA\\Desktop"; 
    public static void main(String[] args) throws InterruptedException, 

      IOException { 
     // multiple commands 
     // /C Carries out the command specified by string and then terminates 
     ProcessBuilder pbC = new ProcessBuilder(//COMPİLE 
       "cmd.exe", "/c", "cd " + backSlashFl + "&& javac " + "Test" + ".java"); 
     Process processC = pbC.start(); 


     ProcessBuilder pb = new ProcessBuilder(//RUN 
       "cmd.exe", "/c", "cd " + backSlashFl + "&& java " + "Test"); 

     Process process = pb.start(); 
     IOThreadHandler outputHandler = new IOThreadHandler(
       process.getInputStream()); 
     outputHandler.start(); 
     process.waitFor(); 
     System.out.println(outputHandler.getOutput()); 
    } 

    private static class IOThreadHandler extends Thread { 
     private InputStream inputStream; 
     private StringBuilder output = new StringBuilder(); 

     IOThreadHandler(InputStream inputStream) { 
      this.inputStream = inputStream; 
     } 

     public void run() { 
      Scanner br = null; 
      try { 
       br = new Scanner(new InputStreamReader(inputStream)); 
       String line = null; 
       while (br.hasNextLine()) { 
        line = br.nextLine(); 
        output.append(line 
          + System.getProperty("line.separator")); 
       } 
      } finally { 
       br.close(); 
      } 
     } 

     public StringBuilder getOutput() { 
      return output; 
     } 
    } 
} 

我認爲它的工作在後面,但我如何才能輸入部分?

這是我想編譯和運行的文件。

import java.awt.*; 
import java.awt.event.*; 
import java.util.Scanner; 

public class numberScan { 
    public static void main(String[] args){ 
    Scanner scan = new Scanner(System.in); 
    System.out.println("Enter the number: "); 
    int a=scan.nextInt(); 
    System.out.println("Number= " + a); 
} 
} 

我在等你的幫助。


Editted

現在,當我運行GUI,運行鍵被按下。你覺得我應該怎麼做?

buttonRun.addActionListener(new ActionListener(){ 
    public void actionPerformed(ActionEvent e){ 

     String backSlashFl = file.getAbsolutePath().replace("\\", "\\\\"); 
     backSlashFl = backSlashFl.replace(flName + ".java", ""); 

     try { 

      execute("cmd.exe", "/c", "cd " + backSlashFl + " && java " + flName); 

      JOptionPane.showMessageDialog(null, "Dosya çalıştı!","Bilgilendirme", 
        JOptionPane.INFORMATION_MESSAGE); 
     } catch (FileNotFoundException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } catch (IOException ae) { 
      // TODO Auto-generated catch block 
      ae.printStackTrace(); 
     } catch (Exception e2){ 
      e2.printStackTrace(); 
     } 

    } 

}); 

當GUI應用程序運行時,此運行按鈕保持不變。

+0

'編輯' 實際上是一個不同的問題。你**可以**這是一個新問題,但這將是一個重複的問題:這已被問** **許多次**之前。長話短說:您必須在新線程中運行包含在您的'actionPerformed'方法中的代碼。粗略地說:用'new Thread(new Runnable(){public void run(){/ *目前在你的方法中的代碼* /})。start();' - 替換這個方法的內容。 ://stackoverflow.com/questions/17241727/java-jbutton-actionperformed-freezing和**許多**其他問題。我建議撤消編輯。 – Marco13

回答

1

給定的代碼有幾個問題。我試圖把它擠進一個評論,但現在決定把它擴大到一個答案:

  • 要編譯的類被稱爲numberScan,但顯然存儲在一個名爲Test.java文件。公共類只能存儲在與該類具有相同名稱的文件中。致電NumberScan,然後致電文件NumberScan.java

  • 您只是試圖打印輸入流提供的輸出。但你是而不是打印錯誤提供的結果流(所以如果有錯誤,你不會看到它們!)。此外,您只打印Process process(用於運行程序)的輸出。您沒有打印用於編譯程序的Process processC的輸出。

  • 的,爲什麼你沒有看到的原因,任何輸出是該行

    System.out.println(outputHandler.getOutput()); 
    

    執行之前完成的過程。您使用了waitFor,但output由不同的線程填充 - 即IOThreadHandlergetOutput方法只能在IOThreadHandler已完成後才能調用,但如果要連續更新輸出,則這將不起作用。

這是不完全清楚你要實現什麼,但是從您提供的代碼猜測,你的目標似乎是創建一個程序,

  • 編譯給定的Java文件
  • 執行生成的Java程序
  • 打印可能的錯誤消息,並且由程序
  • 重要創建的輸出:允許相互作用與程序,在這種意義上說,它應該有可能發送輸入到該程序的System.in

最後兩點特別難以手動存檔。您將不得不設置線程來讀取輸入流和錯誤流。這些將需要一些技巧來確保在程序執行時數據被連續讀取。此外,您必須設置一個線程,將用戶輸入的數據轉發到在其自己的進程中執行的Java程序。

幸運的是,對於Java 7,所有這些都變得相當簡單:您可以簡單地爲所有流設置合適的ProcessBuilder.Redirect(即重定向INHERIT),以便所有流都映射到周圍程序的相應流。

下面是一個例子:

import java.io.IOException; 
import java.lang.ProcessBuilder.Redirect; 
import java.util.Arrays; 

public class ProcessBuilderMultipleCommandsExample { 
    private static String path = "C:\\Users\\xxA\\Desktop"; 

    public static void main(String[] args) 
     throws InterruptedException, IOException { 

     execute("cmd.exe", "/c", "cd " + path + " && javac " + "NumberScan" + ".java"); 
     execute("cmd.exe", "/c", "cd " + path + " && java " + "NumberScan"); 
    } 

    private static void execute(String ... commands) 
     throws IOException, InterruptedException 
    { 
     System.out.println("Executing "+Arrays.asList(commands)); 

     ProcessBuilder processBuilder = new ProcessBuilder(commands); 
     processBuilder.redirectInput(Redirect.INHERIT); 
     processBuilder.redirectOutput(Redirect.INHERIT); 
     processBuilder.redirectError(Redirect.INHERIT); 

     Process process = processBuilder.start(); 
     process.waitFor(); 
    } 
} 
+0

非常感謝, – Okan

+0

現在,當我運行GUI時,Run鍵被按下。我加了我的問題。你可以幫我嗎? – Okan