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'**
在我的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。
谢谢你的答案,但我真的不知道如何使用这个信息来解决我的问题..对不起:/ – ACCESScoPezz
我刚刚发现了什么是“真正的”问题。如果你运行终端或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
谢谢你的额外的信息,但事情是,我希望运行安装在不同的地方,在Linux和OS X的命令行程序,我想执行的“,这“命令找到它,但是当双击时安装路径不在PATH变量内,但是在运行jar槽控制台时不是。双击时,我希望PATH变量与通过控制台时相同。我将编辑我的帖子以显示程序的整个代码。 – ACCESScoPezz
通常,您应该始终为Java程序提供.bat/.sh启动脚本。 – Alexiy
我想我必须这么做,因为我不知道如何解决$ PATH问题。谢谢您的回答。 – ACCESScoPezz