applicationpackager.java
字号:
package piy;
import java.io.*;
import java.util.jar.*;
import java.util.ArrayList;
import javax.swing.*;
import java.awt.*;
/**
* Utility class to collect all of the files needed for an application
* to run and store them together in a Jar file. Also creates a startup
* file to allow the application to run.
* <p>
* @author David Vivash
* @version 1.0.1, 22/04/01
*/
public class ApplicationPackager {
private Application app = null;
private File filename = null;
/**
* Set up the application packager. The filename should be absolute, ie.
* contain directory information as well as the filename.
* @param app the application to be packaged
* @param filename the filename (including directory) to save the application as
*/
public ApplicationPackager(Application app) {
this.app = app;
}
/**
* Display a file dialog for the user to select where to save the application to, then
* save the application and support files.
* @param parent the frame to act as the file dialog's modal parent
*/
public void saveApplication(Frame parent, Class[] actions, Class[] components, Class[] containers, Class[] listeners, Class[] comparators) {
FileDialog dialog = new FileDialog(parent, "Save Application As...", FileDialog.SAVE);
dialog.show();
if (dialog.getFile() != null) {
filename = new File(dialog.getDirectory(), dialog.getFile());
//Make filename end in ".jar" unless an extension has already been specified
if (filename.getName().indexOf('.') < 0) {
filename = new File(filename.getParent(), filename.getName() + ".jar");
}
this.filename = filename;
try{
createPackage(actions, components, containers, listeners, comparators);
//Windows specific. Maybe have an option here or something.
createBatFile();
JOptionPane pane = new JOptionPane("Application successfully created", JOptionPane.INFORMATION_MESSAGE);
JDialog paneDialog = pane.createDialog(null, "Success");
paneDialog.setResizable(false);
paneDialog.show();
} catch (CompilationException e) {
JOptionPane pane = new JOptionPane(
new String[] {"The application could not be packaged", e.getMessage()},
JOptionPane.ERROR_MESSAGE);
JDialog paneDialog = pane.createDialog(null, "Cannot Compile");
paneDialog.setResizable(false);
paneDialog.show();
}
}
}
/**
* Packages the application. That is, it creates a Jar file which includes all
* files needed by the application to run, and saves it along with the application
* file.<p>
* This method makes use, if available, of a file called "support" which contains
* the (fully qualified) class names of all classes that are always needed by a
* compiled application. Actions/usercomponents/usercontainers should not be
* specified here.
*/
public void createPackage(Class[] actions, Class[] components, Class[] containers, Class[] listeners, Class[] comparators)
throws CompilationException
{
File[] supportFiles = getSupportFiles();
boolean error = false; //if an error occurs in the compilation
String message = ""; //error message to display
try{
//first create manifest file
JarOutputStream output = new JarOutputStream(new FileOutputStream(filename));
output.putNextEntry(new JarEntry(JarFile.MANIFEST_NAME));
Manifest manifest = new Manifest();
Attributes att = manifest.getMainAttributes();
att.put(Attributes.Name.MANIFEST_VERSION, "1.0");
att.put(new Attributes.Name("Created-By"), "PIY-II (David Vivash)");
att.put(Attributes.Name.MAIN_CLASS, "piy.PIYRunner");
manifest.write(output);
//Now add each support file to the archive
for (int i=0; i<supportFiles.length; i++) {
String name = supportFiles[i].getName().replace('.', File.separatorChar);
File toLoad = new File(name + ".class");
byte[] classFile = null;
try {
FileInputStream input = new FileInputStream(toLoad);
input.read(classFile = new byte[input.available()]);
input.close();
} catch (Exception e) {
System.err.println("Unable to load class file");
}
if (classFile != null) { //loaded file okay, so add to the jar archive
output.putNextEntry(new JarEntry(name.replace(File.separatorChar, '/') + ".class"));
output.write(classFile);
}
}
//Save application to temporary output
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("temp.out")));
oos.writeObject(app);
oos.flush();
oos.close();
//reload application data, then add it to the jar archive
byte[] classFile = null;
try {
FileInputStream input = new FileInputStream(new File("temp.out"));
input.read(classFile = new byte[input.available()]);
input.close();
} catch (Exception e) {
System.out.println("Unable to load class file");
}
if (classFile != null) { //loaded file okay, so add to the jar archive
output.putNextEntry(new JarEntry("Compiled"));
output.write(classFile);
}
//Add the components/containers/actions and listeners
addClasses(components, output);
addClasses(containers, output);
addClasses(actions, output);
addClasses(listeners, output);
addClasses(comparators, output);
output.close();
} catch (InvalidClassException ex) {
error = true;
message = "Invalid class";
} catch (NotSerializableException ex) {
error = true;
message = "Error adding " + ex.getMessage() + " to the package";
} catch (Exception ex) {
error = true;
message = "The application could not be saved";
}
if (error) throw new CompilationException(message);
}
private void addClasses(Class[] classes, JarOutputStream output) {
//Now add each support file to the archive
for (int i=0; i<classes.length; i++) {
String name = classes[i].getName().replace('.', File.separatorChar);
File toLoad = new File(name + ".class");
byte[] classFile = null;
try {
FileInputStream input = new FileInputStream(toLoad);
input.read(classFile = new byte[input.available()]);
input.close();
if (classFile != null) { //loaded file okay, so add to the jar archive
output.putNextEntry(new JarEntry(name.replace(File.separatorChar, '/') + ".class"));
output.write(classFile);
}
} catch (Exception e) {
//May get this exception if a file is added twice to the same archive
System.out.println("Unable to add class file to application archive (" + toLoad + ")");
}
}
}
/**
* Creates a Windows bat file and saves it in the application save path directory as
* "<filename>.bat".
*/
public void createBatFile() {
String noecho = "@echo off";
String runApp = "javaw -jar " + filename.getName() + " " + filename.getName() + " -lf System";
File savePath = new File(filename.getParent());
File saveDest = new File(savePath, filename.getName()+".bat");
try {
PrintStream os = new PrintStream(new FileOutputStream(saveDest));
os.println(noecho);
os.println(runApp);
os.flush();
os.close();
} catch (Exception e) {
System.out.println("Error saving bat file");
e.printStackTrace();
}
}
/**
* Gets the filenames of the files defined in "support".
* @return an array of files as listed in the "support" file
*/
private File[] getSupportFiles() {
ArrayList names = new ArrayList(8);
BufferedReader in = null;
try{
in = new BufferedReader(new FileReader("support"));
while(in.ready()) names.add(in.readLine()); //read each line of the file
} catch (Exception e) {
System.out.println("Error retrieving support files");
} finally { //close the stream if we can
try { in.close(); } catch (Exception io) {}
}
//create our array of files
File[] toReturn = new File[names.size()];
for (int i=0; i<names.size(); i++) toReturn[i] = new File((String)names.get(i));
return toReturn;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -