2016-09-27 75 views
3

我試圖通過在JavaFX中製作的GUI啓動命令行應用程序。 當我在我的IDE中運行該程序時,它一切正常,但是當我嘗試通過雙擊編譯的.jar文件運行它時,它不會。Java - 從終端運行jar但雙擊休息功能

我已經知道,這可能是因爲PATH或類路徑或工作目錄或類似的東西不同於從終端運行時。

public Button startButton; 
public Button clearButton; 
public Button minButton; 
public Button plusButton; 
public Button clearFieldButton; 
public Button clearLogButton; 
public TextField linkField; 
public TextField qualField; 
public TextArea errorField; 
public ListView<String> historyField; 

private String os; 

public void initialize(){ 
    os = System.getProperty("os.name"); 
    linkField.setText(null); 
    qualField.setText(null); 
    getHistory(); 
    setButtonActions(); 
    Runnable run = new Runnable() { 
     @Override 
     public void run() { 
      linkField.requestFocus(); 
     } 
    }; 
    Platform.runLater(run); 
} 

private void setButtonActions(){ 
    historyField.setOnMouseClicked(new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent mouseEvent) { 
      if(mouseEvent.getClickCount() == 2){ 
       String qual; 
       if(qualField.getText() == null){ 
        qual = "best"; 
       } 
       else{ 
        qual = qualField.getText(); 
       } 
       startStream(historyField.getSelectionModel().getSelectedItem(), qual); 
      } 
     } 
    }); 
    clearButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent actionEvent) { 
      clearHistory(); 
     } 
    }); 
    minButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent actionEvent) { 
      delLast(); 
     } 
    }); 
    plusButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent actionEvent) { 
      writeHistory(linkField.getText()); 
     } 
    }); 
    startButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent actionEvent) { 
      startStream(linkField.getText(),qualField.getText()); 
     } 
    }); 
    clearFieldButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent actionEvent) { 
      linkField.clear(); 
      qualField.clear(); 
     } 
    }); 
    clearLogButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent actionEvent) { 
      errorField.clear(); 
     } 
    }); 
} 

private void delLast(){ 
    LinkedList<String> temp = new LinkedList<>(); 
    try(BufferedReader br = new BufferedReader(new FileReader("history.txt"))){ 
     String line; 
     while((line = br.readLine()) != null){ 
      temp.add(line); 
     } 
     temp.removeLast(); 
     clearHistory(); 
     for (String s : temp) { 
      writeHistory(s); 
     } 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private void clearHistory(){ 
    try(BufferedWriter br = new BufferedWriter(new FileWriter("history.txt"))){ 
     br.write(""); 
     getHistory(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private void getHistory(){ 
    if(!new File("history.txt").exists()){ 
     try(BufferedWriter wr = new BufferedWriter(new FileWriter("history.txt"))) { 
      wr.write(""); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    else{ 
     historyField.getItems().clear(); 
     ArrayList<String> history = new ArrayList<>(); 
     try(BufferedReader br = new BufferedReader(new FileReader("history.txt"))){ 
      String line; 
      while((line = br.readLine()) != null){ 
       history.add(line); 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     historyField.getItems().addAll(history); 
    } 
} 

private boolean checkIfInFile(String link){ 
    try(BufferedReader br = new BufferedReader(new FileReader("history.txt"))){ 
     String line; 
     while ((line = br.readLine()) != null){ 
      if(line.equals(link)){ 
       return true; 
      } 
     } 
     return false; 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return false; 
} 

private void writeHistory(String link){ 
    if(link != null){ 
     try(PrintWriter print = new PrintWriter(new FileWriter("history.txt", true))) { 
      print.append(link).append("\n"); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     getHistory(); 
    } 
} 

private void startStream(String link, String quality){ 
    errorField.setText(""); 
    String command = ""; 
    if(!checkIfInFile(link)){ 
     writeHistory(link); 
    } 
    if(!os.contains("win")){ 
     ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", "/usr/bin/which streamlink"); 
     Map<String, String> env = pb.environment(); 
     env.put("PATH",System.getenv("PATH")); 
     errorField.appendText(env.get("PATH") + "\n"); 
     try(BufferedReader br = new BufferedReader(new InputStreamReader(pb.start().getInputStream()))) { 
      command = br.readLine(); 
      errorField.appendText(command); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     if(quality == null){ 
      command = command + " " + link; 
     } 
     else if(link != null){ 
      command = command + " " + link + " " + quality; 
     } 
    } 
    else{ 
     if(link == null){ 
      command = "streamlink"; 
     } 
     else if(quality == null){ 
      command = "streamlink " + link; 
     } 
     else{ 
      command = "streamlink " + link + " " + quality; 
     } 
    } 
    try { 
     ProcessBuilder pb = new ProcessBuilder("/bin/bash", "-c", command); 
     Process proc = pb.start(); 
     final InputStream in = proc.getInputStream(); 
     Thread outputThread = new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try(BufferedReader br = new BufferedReader(new InputStreamReader(in))){ 
        String read; 
        while((read = br.readLine()) != null){ 
         errorField.appendText(read + "\n"); 
        } 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
     outputThread.start(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

任何幫助將不勝感激。

編輯:忘了提及,雙擊Windows的作品完美。編輯2:**我剛剛發現了什麼是「真正」的問題。如果你運行終端或bash腳本,這是echo $ PATH的結果:'/Users/Vermeulen/.jenv/shims:/opt/local/bin:/opt/local/sbin:/ Library/Frameworks/Python.framework/VE rsions/3.5 /斌:在/ usr/local/bin目錄:在/ usr/bin中:/ bin中:/ usr/sbin目錄:/ sbin目錄:在/ usr/local/bin目錄中:/ opt/x11/bin:/ usr/X11/bi',當你雙擊jar時echo $ PATH的結果是:'/ usr/bin:/ bin:/ usr/sbin:/ sbin'**

+0

通常,您應該始終爲Java程序提供.bat/.sh啓動腳本。 – Alexiy

+0

我想我必須這麼做,因爲我不知道如何解決$ PATH問題。謝謝您的回答。 – ACCESScoPezz

回答

2

在我的Linux機器上雙擊使用我的主目錄作爲工作目錄。因此,如果您嘗試查找與您的jar文件相關的某些文件,它將會失敗。

要解決此問題,你不能用含

java -jar myjarfile.jar 

您要高度重視比可以雙擊Shell腳本(取決於你的Linux分佈)的shell腳本

啓動罐子如果你想通過代碼來解決,試試這個片斷:

CodeSource src = Main.class.getProtectionDomain().getCodeSource(); 
File pathToJar = new File(src.getLocation().toURI()); 
System.out.println(pathToJar.getAbsolutePath()); 

它返回你的主類文件或者目錄或完整路徑的JAR文件。取決於你如何開始你的程序。 使用此信息來查找您的文件。

----------------更新1

您沒有說明到底是什麼你正在嘗試做的。 如果要爲外部命令設置環境變量(如PATH),請使用ProcessBuilder

ProcessBuilder builder = new ProcessBuilder("myprogramm", "firstArg", "secondArg"); 
Map<String, String> environment = builder.environment(); 
environment.put("PATH", environment.get("PATH") + ":/my/path"); 
Process process = builder.start(); 
OutputStream outputStream = process.getOutputStream(); 
process.waitFor(); 

欲瞭解更多信息,請閱讀ProcessBuilder

+0

謝謝你的答案,但我真的不知道如何使用這個信息來解決我的問題..對不起:/ – ACCESScoPezz

+0

我剛剛發現了什麼是「真正的」問題。如果你運行終端或bash腳本,這是echo $ PATH的結果:'/ Users/Vermeulen /。jenv /墊片中:/ opt/local/bin目錄中:/ opt/local/sbin中:/Library/Frameworks/Python.framework/Versions/3.5/bin:在/ usr/local/bin目錄:在/ usr/bin中:/ bin中:在/ usr/sbin目錄:/ sbin目錄:在/ usr/local/bin目錄中:/ opt/X11/bin中:在/ usr/X11/BI '當你雙擊的jar回聲$ PATH的結果是:' 在/ usr/bin中:/ bin中:/ usr/sbin目錄:/ sbin目錄 – ACCESScoPezz

+0

謝謝你的額外的信息,但事情是,我希望運行安裝在不同的地方,在Linux和OS X的命令行程序,我想執行的「,這「命令找到它,但是當雙擊時安裝路徑不在PATH變量內,但是在運行jar槽控制檯時不是。雙擊時,我希望PATH變量與通過控制檯時相同。我將編輯我的帖子以顯示程序的整個代碼。 – ACCESScoPezz