Java - 从终端运行jar但双击休息功能

问题描述:

我试图通过在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

在我的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

你可以在jar中分享Manifest.mf文件吗?应该有正确设置的主类。 please check this

其次check this as well。我希望jdk已经在属性选项卡中正确设置。