有没有什么方法可以制作一个可执行的.jar,它会在双击时打开命令行?
我正在制作基于文本的冒险游戏。截至目前,它只是一个有房间的迷宫。最终它会变得更大更深入,但是现在我只想让基本结构失效。无论如何,为了完成这项工作,我一直在从System.out.printf命令和java.util.Scanner获取输出和输入。到目前为止,这一切都工作得很漂亮,但我发现当我尝试将这个问题发送给其他不知道如何或者不想从命令行运行程序的人时,我会遇到问题。
答案 0 :(得分:14)
我在寻找答案时发现了这一点,我最后写了这个:
/**
* This opens a command line and runs some other class in the jar
* @author Brandon Barajas
*/
import java.io.*;
import java.awt.GraphicsEnvironment;
import java.net.URISyntaxException;
public class Main{
public static void main (String [] args) throws IOException, InterruptedException, URISyntaxException{
Console console = System.console();
if(console == null && !GraphicsEnvironment.isHeadless()){
String filename = Main.class.getProtectionDomain().getCodeSource().getLocation().toString().substring(6);
Runtime.getRuntime().exec(new String[]{"cmd","/c","start","cmd","/k","java -jar \"" + filename + "\""});
}else{
THEMAINCLASSNAMEGOESHERE.main(new String[0]);
System.out.println("Program has ended, please type 'exit' to close the console");
}
}
}
不确定我的答案是否仍然相关,但随时可以将其与o /
中保留的评论一起使用我能想到的唯一缺陷就是它在程序完成后让cmd窗口保持打开状态。
用法:将此类放在与主类相同的包中并将其设置为主类,如果未打开,则打开命令提示符窗口,或者如果打开一个命令提示符窗口,则启动主类。 jar文件的名称/位置是自动的。专为Windows设计,但如果你想要它用于另一个系统,只需给我留言,我就会修复它。 (我可以进行操作系统检测,但是我很懒,只是这样做,所以我可以将双击jar文件交给我使用Windows的教授。)
答案 1 :(得分:6)
如果您想要完全控制,可以在Swing中实现一个控制台窗口,它可以完成现在的操作。
如果您无法打开所述窗口(如果无头)或用户在命令行上询问它,那么只需默认为您当前的行为。
答案 2 :(得分:4)
双击一个jar会打开它,使用您在操作系统中与其关联的任何应用程序。默认情况下,javaw [.exe]通常与jar文件相关联。这是没有终端窗口的二进制文件。要在双击时查看终端,您需要将java [.exe]二进制文件与jar文件相关联。
答案 3 :(得分:2)
或者你可以提供一个.sh .bat,它将打开一个终端并在其中调用你的java。
答案 4 :(得分:1)
只要使用java.exe执行.jar,就会始终显示命令行窗口。使用javaw.exe执行它会阻止这种情况。
进一步阅读: http://download.oracle.com/javase/1.4.2/docs/tooldocs/windows/java.html
答案 5 :(得分:1)
所以这是我的解决方案,我使用了@Brandon Barajas的代码并对其进行了修改。它创建一个批处理文件,单独启动程序。
public static void main(String[] args){
Console console = System.console();
if(console == null && !GraphicsEnvironment.isHeadless()) {
String filename = YOURMAINCALSS.class.getProtectionDomain().getCodeSource().getLocation().toString().substring(6);
try {
File batch = new File("Launcher.bat");
if(!batch.exists()){
batch.createNewFile();
PrintWriter writer = new PrintWriter(batch);
writer.println("@echo off");
writer.println("java -jar "+filename);
writer.println("exit");
writer.flush();
}
Runtime.getRuntime().exec("cmd /c start \"\" "+batch.getPath());
} catch(IOException e) {
e.printStackTrace();
}
} else {
//your program code...
}
}
如果您需要,可以在“退出”打印之前添加 writer.println(“暂停”); ,以便在程序完成后保持窗口打开。然后,您需要按 ENTER 关闭窗口。
答案 6 :(得分:1)
您可以使用此程序。该程序为JAR程序创建一个控制台(当通过双击运行JAR程序时)。
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.text.*;
import javax.swing.border.*;
class InitComponents {
public static JFrame setupJFrameAndGet(String title, int width, int height) {
JFrame tmpJF = new JFrame(title);
tmpJF.setSize(width, height);
tmpJF.setLocationRelativeTo(null);
tmpJF.setLayout(null);
tmpJF.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
return tmpJF;
} // end of setupJFrameAndGet
public static JTextArea setupJTextAreaAndGet(String text, int rows, int columns, boolean setEditableFlag, boolean setLineWrapFlag, boolean setWrapStyleWordFlag, boolean setBoundsFlag, int xpos, int ypos, int width, int height) {
JTextArea tmpJTA = new JTextArea(text, rows, columns);
tmpJTA.setEditable(setEditableFlag);
tmpJTA.setLineWrap(setLineWrapFlag);
tmpJTA.setWrapStyleWord(setWrapStyleWordFlag);
if (setBoundsFlag == true) {
tmpJTA.setBounds(xpos, ypos, width, height);
}
return tmpJTA;
} // end of setupJTextAreaAndGet
public static JScrollPane setupScrollableJTextAreaAndGet(JTextArea jta, int xpos, int ypos, int width, int height) {
JScrollPane tmpJSP = new JScrollPane(jta);
tmpJSP.setBounds(xpos, ypos, width, height);
return tmpJSP;
} // end of setupScrollableJTextAreaAndGet
public static JMenuBar setupJMenuBarAndGet() {
JMenuBar tmpJMB = new JMenuBar();
return tmpJMB;
} // end of setupJMenuBarAndGet
public static JMenu setupJMenuAndGet(String text) {
JMenu tmpJM = new JMenu(text);
return tmpJM;
} // end of setupJMenuAndGet
public static JMenuItem setupJMenuItemAndGet(String text) {
JMenuItem tmpJMI = new JMenuItem(text);
return tmpJMI;
} // end of setupJMenuItemAndGet
}// end of InitComponents
public class ConsoleForJARPrograms implements KeyListener, ActionListener {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int screenWidth = screenSize.width;
int screenHeight = screenSize.height;
String title = null;
String text = null;
JFrame jf = null;
JTextArea jta = null;
JScrollPane jsp = null;
JMenuBar jmb = null;
JMenu jm = null;
JMenuItem jmi = null;
int initialCaretPosition = 0;
int currentCaretPosition = 0;
boolean inputAvailable = false;
// key codes
int BACKSPACE = 8;
int ENTER = 10;
int PG_UP = 33; // do nothing for this key pressed
int PG_DN = 34; // do nothing for this key pressed
int END = 35;
int HOME = 36;
int LEFT_ARROW = 37;
int UP_ARROW = 38; // do nothing for this key pressed
//int RIGHT_ARROW = 39; // handled by JTextArea
int DOWN_ARROW = 40; // do nothing for this key pressed
int CTRL = 128;
int A = 65; // disable ctrl-a
int H = 72; // handle ctrl-h
//int DELETE = 127; // handled by JTextArea
public void actionPerformed(ActionEvent ae) {
int cCurrPos = jta.getCaretPosition();
jta.selectAll();
jta.copy();
jta.select(cCurrPos, cCurrPos);
} // end of actionPerformed
public void keyTyped(KeyEvent ke) {
} // end of keyTyped
public void keyReleased(KeyEvent ke) {
} // end of keyReleased
public void keyPressed(KeyEvent ke) {
int keyCode = ke.getKeyCode();
if ((keyCode == PG_UP) || (keyCode == PG_DN) || (keyCode == UP_ARROW) || (keyCode == DOWN_ARROW) || ((keyCode == A) && (ke.getModifiersEx() == CTRL))) {
ke.consume();
} else if ((keyCode == LEFT_ARROW) || (keyCode == BACKSPACE) || ((keyCode == H) && (ke.getModifiersEx() == CTRL))) {
synchronized(this) {
if (jta.getCaretPosition() <= initialCaretPosition) {
ke.consume();
}
} // end of synchronized block
} else if (keyCode == HOME) {
synchronized(this) {
jta.setCaretPosition(initialCaretPosition);
ke.consume();
} // end of synchronized block
} else if (keyCode == END) {
synchronized(this) {
jta.setCaretPosition(jta.getDocument().getLength());
ke.consume();
} // end of synchronized block
} else if (keyCode == ENTER) {
jta.setCaretPosition(jta.getDocument().getLength());
synchronized(this) {
currentCaretPosition = jta.getCaretPosition();
// If character at initial caret position is newline then it means that the user has
// pressed enter without enetring any other character. Also, the code gets called here
// as soon as enter is pressed which means that the caret position (jta.getCaretPosition())
// of the document will be incremented by 1 by the system after this code returns.
// This means that if at initial caret position, the character is newline, then we must ignore
// this enter and increment initial caret position by 1 and do not set inputAvailable to true.
try {
String charAtInitialCaretPosition = jta.getText(initialCaretPosition, 1);
if ((charAtInitialCaretPosition.equals("\n")) == true) {
initialCaretPosition++;
}
} catch (Exception e) {
}
/*
debug: start
try {
System.out.println("keyPressed (1): initial = " + initialCaretPosition + ", current = " + currentCaretPosition + ", System current = " + jta.getDocument().getLength());
String initialString = jta.getText(initialCaretPosition, 1);
String currentString = jta.getText(currentCaretPosition, 1);
System.out.println("char at initial = " + initialString + ", char at current = " + currentString);
if ((initialString.equals("\n")) == true) {
System.out.println("char at initial is newline");
}
if ((currentString.equals("\n")) == true) {
System.out.println("char at current is newline");
}
} catch (Exception e) {
}
debug:end
*/
if ((currentCaretPosition - initialCaretPosition) > 0) {
inputAvailable = true;
notifyAll();
}
} // end of synchronized block
} // end of if else if
} // end of keyPressed
String getInputFromJTextArea(JTextArea jta) {
int len = 0;
String inputFromUser = "";
while (true) {
synchronized(this) {
if (inputAvailable == true) {
len = currentCaretPosition - initialCaretPosition;
try {
inputFromUser = jta.getText(initialCaretPosition, len);
initialCaretPosition = currentCaretPosition;
} catch (Exception e) {
inputFromUser = "";
return inputFromUser;
} // end of outer try catch
/*
The following lines of code are not needed now.
if ((len == 1) && (inputFromUser.equals("\n")) == true) {
try {
wait();
continue;
} catch (Exception e) {
} // end of try catch
} else if (Character.compare(inputFromUser.charAt(0), '\n') == 0) { // matched
// remove first character from inputFromUser
inputFromUser = inputFromUser.substring(1);
}
*/
inputAvailable = false;
return inputFromUser;
} else {
try {
wait();
continue;
} catch (Exception e) {
} // end of try catch
} // end of if else inputAvailable
} // end of synchronized block
} // end of while true
} // end of getInoutFromJtextArea
void outputToJTextArea(JTextArea jta, String text) {
jta.append(text);
jta.setCaretPosition(jta.getDocument().getLength());
synchronized(this) {
initialCaretPosition = jta.getCaretPosition();
}
} // end of outputToJTextArea
void begin() {
while (true) {
outputToJTextArea(jta, "Enter some input (press enter after inputting): ");
String input = getInputFromJTextArea(jta);
outputToJTextArea(jta, "User input was: " + input + "\n\n");
}
} // end of begin
void configureJTextAreaForInputOutput(JTextArea jta) {
jta.addKeyListener(this);
// remove all mouse listeners
for (MouseListener listener : jta.getMouseListeners()) {
//outputToJTextArea(jta, "\nRemoving mouse listener\n");
jta.removeMouseListener(listener);
}
// remove all mouse motion listeners
for (MouseMotionListener listener : jta.getMouseMotionListeners()) {
//outputToJTextArea(jta, "\nRemoving mouse motion listener\n");
jta.removeMouseMotionListener(listener);
}
// remove all mouse wheel listeners
for (MouseWheelListener listener : jta.getMouseWheelListeners()) {
//outputToJTextArea(jta, "\nRemoving mouse wheel listener\n");
jta.removeMouseWheelListener(listener);
}
} // end of configureJTextAreaForInputOutput
void createAndShowGUI() {
title = "Console";
jf = InitComponents.setupJFrameAndGet(title, screenWidth - 150, screenHeight - 100);
jta = InitComponents.setupJTextAreaAndGet("", 1000, 100, true, true, true, false, 0, 0, 0, 0);
configureJTextAreaForInputOutput(jta);
jsp = InitComponents.setupScrollableJTextAreaAndGet(jta, 10, 10, screenWidth - 180, screenHeight - 180);
jsp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jsp.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
jf.add(jsp);
//jf.setLocation(screenWidth / 5, screenHeight / 6);
jmb = InitComponents.setupJMenuBarAndGet();
jm = InitComponents.setupJMenuAndGet("Copy All to Clipboard");
jm.setBorder(BorderFactory.createLineBorder(Color.green, 2));
jmi = InitComponents.setupJMenuItemAndGet("Copy All to Clipboard");
jm.add(jmi);
jmb.add(jm);
jmi.addActionListener(this);
jf.setJMenuBar(jmb);
jf.setVisible(true);
} // end of createAndShowGUI
public static void main(String[] args) {
ConsoleForJARPrograms cfjp = new ConsoleForJARPrograms();
cfjp.createAndShowGUI();
cfjp.begin();
} // end of main
} // end of ConsoleForJARPrograms
答案 7 :(得分:0)
我想最简单的方法是为你的jar文件编写一个简单的快捷方式。例如eclipse(像大多数ide一样)能够导出一个包含所有必需库等的jar文件,所以你只需要设置快捷命令,如“java -jar filePath / file.jar”(filePath:eg ./bin/file)的.jar)
答案 8 :(得分:0)
实现此目的的一种方法是使用以下命令创建.bat文件:“java -jar filePath / yourfile.jar”(不带“”)。确保包含文件路径,否则将找不到您的文件。 虽然问题已经得到解答,但这是一种简单的方法。
答案 9 :(得分:0)
您可以使用Swing或Awt创建自己的窗口,使用TextPane,唯一的问题是如何输入和使用,就像cmd应该做的那样。但你可以随时通过提醒和所有人来做这件事......
其他方式,直接从批处理文件运行,显示在控制台上。
您也应该考虑,直接批量制作游戏......不是一种糟糕的语言,并且存在于每个Windows操作系统上。
(希望很有用('因为我是新的),我的英语不是那么糟糕......)
答案 10 :(得分:0)
答案 11 :(得分:0)
我找到了另一种方法...例如,对于my项目,它在bar包中具有foo类:
java -cp myproject.jar; bar.foo
答案 12 :(得分:0)
我写了一个小片段,它使用与Brandon Barajas解决方案类似的方法。 它一口气支持Mac(未经测试),Linux(经过xfce测试)和Windows(cmd)(尽管您可能需要自定义linux终端命令,因为有很多不同的命令)。
https://github.com/Lartsch/java-selfconsole/
在以下情况下非常有帮助: