我用3个Jbuttons创建了一个JFrame。我想按钮启动位于同一文件夹中的不同.exe文件。这可能吗?如果是,我应该为actionListener写什么?另一方面,是否可以使用JButton启动主类,而不是启动exe文件?如果是,我应该为actionListener写什么?
注意:.exe文件是从java主程序创建的。
JButton button1 = new JButton("Program1"); //The JButton name.
frame.add(button1); //Add the button to the JFrame.
button1.addActionListener().... // how to launch the .exe file
提前致谢
答案 0 :(得分:4)
Runtime.getRuntime().exec( ... );
或使用ProcessBuilder类。
您应该能够在网络上找到使用这些类的示例。
编辑:例如,要在Windows中启动Notepad exe,您可以这样做:
Process process = Runtime.getRuntime().exec( "cmd.exe /C start notepad" );
如果要执行某个类,则需要以与从命令行调用它相同的方式调用JVM。
答案 1 :(得分:1)
您可能有兴趣查看executing an external process。
答案 2 :(得分:1)
我认为如果你没有从GUI调用它,你会使用Runtime.exec()或ProcessBuilder,类似于调用exe程序的方式。需要注意的一些事情是,您可能希望在Swing主线程(EDT)的后台线程上调用Runtime.exec(),例如由SwingWorker对象提供。否则,当exe程序接管Swing线程时,GUI可能会冻结。此外,您还需要了解有关调用此文章中显示的Runtime.exec()的所有警告, When Runtime.exec() won't,可能是关于这个主题的最好的文章之一 - 强烈推荐!
问题:这句话是什么意思,因为我不清楚?:
注意:program.exe文件是从java主程序创建的。
答案 3 :(得分:1)
这是一个替代答案,无需通过Runtime.getRuntime()。exec(...)创建新进程 - 您也可以维护您的System.in/out频道。然而, 如果你是java编程世界的新手,并试图学习绳索,我建议遵循camickr的建议,而不是如下所述搞乱ClassLoader。
我假设您需要运行的类是自包含的(不使用内部类)而不是已经存在于类路径或jar文件中,因此您可以创建一个实例并调用其main()。 如果涉及多个类文件,只需重复加载它们的方法。
所以,在你的JButton addActionListener()的ActionListener中,ed to ...
public void actionPerformed (ActionEvent e) {
String classNameToRun = e.getActionCommand(); // Or however you want to get it
try {
new MyClassLoader().getInstance(classNameToRun).main (null);
} catch (ClassNotFoundException ce) {
JOptionPane.showMessageDialog (null, "Sorry, Cannot load class "+classNameToRun,
"Your title", JOptionPane.ERROR_MESSAGE);
}}
您的类路径中已经需要一个新类MyClassLoader。这是一个伪代码:
import java.io.*;
import java.security.*;
public class MyClassLoader extends ClassLoader {
protected String classDirectory = "dirOfClassFiles" + File.separator,
packageName = "packageNameOfClass.";
/**
* Given a classname, get contents of the class file and return it as a byte array.
*/
private byte[] getBytes (String className) throws IOException {
byte[] classBytes = null;
File file = new File (classDirectory + className + ".class");
// Find out length of the file and assign memory
// Deal with FileNotFoundException if it is not there
long len = file.length();
classBytes = new byte[(int) len];
// Open the file
FileInputStream fin = new FileInputStream (file);
// Read it into the array; if we don't get all, there's an error.
// System.out.println ("Reading " + len + " bytes");
int bCount = fin.read (classBytes);
if (bCount != len)
throw new IOException ("Found "+bCount+" bytes, expecting "+len );
// Don't forget to close the file!
fin.close();
// And finally return the file contents as an array
return classBytes;
}
public Class loadClass (String className, boolean resolve)
throws IOException, ClassNotFoundException,
IllegalAccessException, InstantiationException {
Class myClass = findLoadedClass (packageName + className);
if (myClass != null)
return myClass;
byte[] rawBytes = getBytes (className);
myClass = defineClass (packageName + className,
rawBytes, 0, rawBytes.length);
// System.out.println ("Defined class " +packageName + className);
if (myClass == null)
return myClass;
if (resolve)
resolveClass (myClass);
return myClass;
}
public Object getInstance (String className) throws ClassNotFoundException {
try {
return loadClass (className, true).newInstance();
} catch (InstantiationException inExp) { inExp.printStackTrace();
} catch (IllegalAccessException ilExp) { ilExp.printStackTrace();
} catch (IOException ioExp) { ioExp.printStackTrace();
}
return null;
}
}
注意: 当您尝试加载的类驻留在本地计算机上并且从命令行运行java时,这很有效。我从来没有成功试图让applet从某个servlet下载一个类文件并加载它 - 安全性不允许这样做。在这种情况下,解决方法只是在另一个窗口中运行另一个applet,但这是另一个线程。上面的类加载解决了必须对你可能需要的每个类文件进行查询的问题 - 只是为了启动GUI。祝你好运, - M.S。