mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-24 22:11:39 +00:00
659 lines
25 KiB
Java
659 lines
25 KiB
Java
/*
|
|
* Copyright (C) 2010-2011 JPEXS
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
package com.jpexs.asdec;
|
|
|
|
import com.jpexs.asdec.abc.NotSameException;
|
|
import com.jpexs.asdec.gui.AboutDialog;
|
|
import com.jpexs.asdec.gui.LoadingDialog;
|
|
import com.jpexs.asdec.gui.ModeFrame;
|
|
import com.jpexs.asdec.gui.View;
|
|
import com.jpexs.asdec.gui.proxy.ProxyFrame;
|
|
import com.jpexs.asdec.tags.DoABCTag;
|
|
import com.jpexs.asdec.tags.Tag;
|
|
import com.jpexs.proxy.Replacement;
|
|
|
|
import javax.swing.*;
|
|
import javax.swing.filechooser.FileFilter;
|
|
import java.awt.*;
|
|
import java.awt.event.ActionEvent;
|
|
import java.awt.event.ActionListener;
|
|
import java.awt.event.MouseAdapter;
|
|
import java.awt.event.MouseEvent;
|
|
import java.io.*;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
/**
|
|
* Main executable class
|
|
*
|
|
* @author JPEXS
|
|
*/
|
|
public class Main {
|
|
|
|
public static com.jpexs.asdec.abc.gui.MainFrame abcMainFrame;
|
|
public static com.jpexs.asdec.action.gui.MainFrame actionMainFrame;
|
|
public static ProxyFrame proxyFrame;
|
|
public static String file;
|
|
public static String maskURL;
|
|
public static SWF swf;
|
|
public static final String version = "beta1";
|
|
public static String applicationName = "JP ActionScript Decompiler v." + version;
|
|
public static String shortApplicationName = "JPAD v."+version;
|
|
public static LoadingDialog loadingDialog;
|
|
public static ModeFrame modeFrame;
|
|
private static boolean working = false;
|
|
private static TrayIcon trayIcon;
|
|
private static MenuItem stopMenuItem;
|
|
private static boolean commandLineMode=false;
|
|
|
|
public static boolean isCommandLineMode(){
|
|
return commandLineMode;
|
|
}
|
|
|
|
public static boolean DEBUG_COPY = false;
|
|
/** Debug mode = throwing an error when comparing original file and recompiled */
|
|
public static boolean DEBUG_MODE = false;
|
|
/** Turn off reading unsafe tags (tags which can cause problems with recompiling)*/
|
|
public static boolean DISABLE_DANGEROUS = false;
|
|
/** Turn off resolving constants in ActionScript 2 */
|
|
public static final boolean RESOLVE_CONSTANTS = true;
|
|
/** Turn off decompiling if needed */
|
|
public static final boolean DO_DECOMPILE=true;
|
|
/** Find latest constant pool in the code */
|
|
public static final boolean LATEST_CONSTANTPOOL_HACK=false;
|
|
/** Dump tags to stdout */
|
|
public static boolean dump_tags = false;
|
|
|
|
//using parameter names in decompiling may cause problems because oficial programs like Flash CS 5.5 inserts wrong parameter names indices
|
|
public static final boolean PARAM_NAMES_ENABLE=false;
|
|
|
|
public static String getFileTitle() {
|
|
if (maskURL != null) return maskURL;
|
|
return file;
|
|
}
|
|
|
|
/**
|
|
* List of replacements
|
|
*/
|
|
public static java.util.List<Replacement> replacements = new ArrayList<Replacement>();
|
|
|
|
|
|
private static String getASDecHome() {
|
|
String dir = ".";//System.getProperty("user.home");
|
|
if (!dir.endsWith(File.separator)) dir += File.separator;
|
|
dir += "config" + File.separator;
|
|
return dir;
|
|
}
|
|
|
|
private static String getReplacementsFile() {
|
|
return getASDecHome() + "replacements.ini";
|
|
}
|
|
|
|
/**
|
|
* Saves replacements to file for future use
|
|
*/
|
|
public static void saveReplacements() {
|
|
try {
|
|
if(replacements.isEmpty()){
|
|
File rf=new File(getReplacementsFile());
|
|
if(rf.exists()) rf.delete();
|
|
}else{
|
|
File f = new File(getASDecHome());
|
|
if (!f.exists()) f.mkdir();
|
|
PrintWriter pw = new PrintWriter(new FileWriter(getReplacementsFile()));
|
|
for (Replacement r : replacements) {
|
|
pw.println(r.urlPattern);
|
|
pw.println(r.targetFile);
|
|
}
|
|
pw.close();
|
|
}
|
|
} catch (IOException e) {
|
|
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load replacements from file
|
|
*/
|
|
public static void loadReplacements() {
|
|
replacements = new ArrayList<Replacement>();
|
|
try {
|
|
BufferedReader br = new BufferedReader(new FileReader(getReplacementsFile()));
|
|
String s = "";
|
|
while ((s = br.readLine()) != null) {
|
|
Replacement r = new Replacement(s, br.readLine());
|
|
replacements.add(r);
|
|
}
|
|
br.close();
|
|
} catch (IOException e) {
|
|
|
|
}
|
|
}
|
|
|
|
public static boolean isWorking() {
|
|
return working;
|
|
}
|
|
|
|
public static void showProxy() {
|
|
if (proxyFrame == null) proxyFrame = new ProxyFrame();
|
|
proxyFrame.setVisible(true);
|
|
proxyFrame.setState(Frame.NORMAL);
|
|
}
|
|
|
|
public static void startWork(String name) {
|
|
working = true;
|
|
if(abcMainFrame!=null)
|
|
abcMainFrame.setStatus(name);
|
|
if(actionMainFrame!=null)
|
|
actionMainFrame.setStatus(name);
|
|
if(Main.isCommandLineMode()){
|
|
System.out.println(name);
|
|
}
|
|
}
|
|
|
|
public static void stopWork() {
|
|
working = false;
|
|
if(abcMainFrame!=null)
|
|
abcMainFrame.setStatus("");
|
|
if(actionMainFrame!=null)
|
|
actionMainFrame.setStatus("");
|
|
}
|
|
|
|
public static SWF parseSWF(String file) throws Exception {
|
|
FileInputStream fis = new FileInputStream(file);
|
|
InputStream bis = new BufferedInputStream(fis);
|
|
SWF locswf = new SWF(bis);
|
|
return locswf;
|
|
}
|
|
|
|
|
|
public static void saveFile(String outfile) throws IOException {
|
|
file = outfile;
|
|
swf.saveTo(new FileOutputStream(outfile));
|
|
}
|
|
|
|
|
|
public static boolean exportSWF(String inFile,String outdir,boolean isPcode) throws Exception {
|
|
SWF swf = parseSWF(inFile);
|
|
boolean asFound=false;
|
|
for (Tag t : swf.tags) {
|
|
if (t instanceof DoABCTag){
|
|
((DoABCTag)t).abc.export(outdir,isPcode);
|
|
asFound=true;
|
|
}
|
|
}
|
|
return asFound;
|
|
}
|
|
|
|
private static class OpenFileWorker extends SwingWorker {
|
|
@Override
|
|
protected Object doInBackground() throws Exception {
|
|
try {
|
|
swf = parseSWF(Main.file);
|
|
FileInputStream fis = new FileInputStream(file);
|
|
DEBUG_COPY = true;
|
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
|
try {
|
|
swf.saveTo(baos);
|
|
} catch (NotSameException nse) {
|
|
if (DEBUG_MODE) {
|
|
nse.printStackTrace();
|
|
System.exit(0);
|
|
}
|
|
JOptionPane.showMessageDialog(null, "WARNING: The SWF decompiler may have problems saving this file. Recommended usage is READ ONLY.");
|
|
}
|
|
DEBUG_COPY = false;
|
|
//DEBUG_COPY=true;
|
|
} catch (Exception ex) {
|
|
if(DEBUG_MODE)
|
|
{
|
|
ex.printStackTrace();
|
|
}
|
|
JOptionPane.showMessageDialog(null, "Cannot load SWF file.");
|
|
loadingDialog.setVisible(false);
|
|
return false;
|
|
}
|
|
List<Tag> listAbc = new ArrayList<Tag>();
|
|
for (Tag t : swf.tags) {
|
|
if (t instanceof DoABCTag) listAbc.add(t);
|
|
}
|
|
|
|
|
|
if (false) {
|
|
JOptionPane.showMessageDialog(null, "This SWF file does not contain any ActionScript parts");
|
|
loadingDialog.setVisible(false);
|
|
if (!openFileDialog()) {
|
|
System.exit(0);
|
|
}
|
|
} else {
|
|
if (listAbc.size() > 0) {
|
|
List<DoABCTag> listAbc2 = new ArrayList<DoABCTag>();
|
|
for (Tag tag : listAbc) {
|
|
listAbc2.add((DoABCTag) tag);
|
|
}
|
|
abcMainFrame = new com.jpexs.asdec.abc.gui.MainFrame(listAbc2);
|
|
abcMainFrame.display();
|
|
} else {
|
|
actionMainFrame = new com.jpexs.asdec.action.gui.MainFrame(swf.tags);
|
|
actionMainFrame.display();
|
|
}
|
|
}
|
|
loadingDialog.setVisible(false);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public static boolean openFile(String swfFile) {
|
|
if (abcMainFrame != null)
|
|
abcMainFrame.setVisible(false);
|
|
if (actionMainFrame != null)
|
|
actionMainFrame.setVisible(false);
|
|
Main.file = swfFile;
|
|
if(Main.loadingDialog == null)
|
|
{
|
|
Main.loadingDialog=new LoadingDialog();
|
|
}
|
|
Main.loadingDialog.setVisible(true);
|
|
(new OpenFileWorker()).execute();
|
|
return true;
|
|
}
|
|
|
|
|
|
public static boolean saveFileDialog() {
|
|
JFileChooser fc = new JFileChooser();
|
|
JFrame f=new JFrame();
|
|
View.setWindowIcon(f);
|
|
int returnVal = fc.showSaveDialog(f);
|
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
|
File file = fc.getSelectedFile();
|
|
try {
|
|
Main.saveFile(file.getAbsolutePath());
|
|
maskURL = null;
|
|
return true;
|
|
} catch (IOException ex) {
|
|
JOptionPane.showMessageDialog(null, "Cannot write to the file");
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public static boolean openFileDialog() {
|
|
maskURL = null;
|
|
JFileChooser fc = new JFileChooser();
|
|
// FIXME debug only, think about keeping/removing it
|
|
fc.setCurrentDirectory(new File("."));
|
|
fc.setFileFilter(new FileFilter() {
|
|
|
|
@Override
|
|
public boolean accept(File f) {
|
|
return (f.getName().endsWith(".swf")) || (f.isDirectory());
|
|
}
|
|
|
|
@Override
|
|
public String getDescription() {
|
|
return "SWF files (*.swf)";
|
|
}
|
|
|
|
});
|
|
JFrame f=new JFrame();
|
|
View.setWindowIcon(f);
|
|
int returnVal = fc.showOpenDialog(f);
|
|
if (returnVal == JFileChooser.APPROVE_OPTION) {
|
|
File selfile = fc.getSelectedFile();
|
|
Main.openFile(selfile.getAbsolutePath());
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
public static void showModeFrame() {
|
|
if (modeFrame == null) modeFrame = new ModeFrame();
|
|
modeFrame.setVisible(true);
|
|
}
|
|
|
|
|
|
/**
|
|
* Script for updating license header in java files :-)
|
|
* @param dir Star directory (e.g. "src/")
|
|
*/
|
|
public static void updateLicenseInDir(File dir){
|
|
int defaultStartYear=2010;
|
|
int defaultFinalYear=2011;
|
|
String defaultAuthor="JPEXS";
|
|
String defaultYearStr=""+defaultStartYear;
|
|
if(defaultFinalYear!=defaultStartYear){
|
|
defaultYearStr+="-"+defaultFinalYear;
|
|
}
|
|
String license="/*\r\n * Copyright (C) {year} {author}\r\n * \r\n * This program is free software: you can redistribute it and/or modify\r\n * it under the terms of the GNU General Public License as published by\r\n * the Free Software Foundation, either version 3 of the License, or\r\n * (at your option) any later version.\r\n * \r\n * This program is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r\n * GNU General Public License for more details.\r\n * \r\n * You should have received a copy of the GNU General Public License\r\n * along with this program. If not, see <http://www.gnu.org/licenses/>.\r\n */\r\n";
|
|
|
|
File files[]=dir.listFiles();
|
|
for(File f:files){
|
|
if(f.isDirectory()){
|
|
updateLicenseInDir(f);
|
|
}else{
|
|
if(f.getName().endsWith(".java")){
|
|
ByteArrayOutputStream baos=new ByteArrayOutputStream();
|
|
PrintWriter pw=null;
|
|
try {
|
|
pw = new PrintWriter(new OutputStreamWriter(baos, "utf8"));
|
|
} catch (UnsupportedEncodingException ex) {
|
|
|
|
}
|
|
try {
|
|
BufferedReader br=new BufferedReader(new FileReader(f));
|
|
String s="";
|
|
boolean packageFound=false;
|
|
String author=defaultAuthor;
|
|
String yearStr=defaultYearStr;
|
|
while((s=br.readLine())!=null){
|
|
if(!packageFound){
|
|
if(s.trim().startsWith("package")){
|
|
packageFound=true;
|
|
pw.println(license.replace("{year}", yearStr).replace("{author}", author));
|
|
}else{
|
|
Matcher mAuthor=Pattern.compile("^.*Copyright \\(C\\) ([0-9]+)(-[0-9]+)? (.*)$").matcher(s);
|
|
if(mAuthor.matches()){
|
|
author=mAuthor.group(3).trim();
|
|
int startYear=Integer.parseInt(mAuthor.group(1).trim());
|
|
if(startYear==defaultFinalYear){
|
|
yearStr=""+startYear;
|
|
}else{
|
|
yearStr=""+startYear+"-"+defaultFinalYear;
|
|
}
|
|
if(!author.equals(defaultAuthor)){
|
|
System.out.println("Detected nodefault author:"+author+" in "+f.getAbsolutePath());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if(packageFound){
|
|
pw.println(s);
|
|
}
|
|
}
|
|
br.close();
|
|
pw.close();
|
|
} catch (IOException ex) {
|
|
|
|
}
|
|
|
|
FileOutputStream fos;
|
|
try {
|
|
fos = new FileOutputStream(f);
|
|
fos.write(baos.toByteArray());
|
|
fos.close();
|
|
} catch (IOException ex) {
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public static void badArguments(){
|
|
System.err.println("Error: Bad Commandline Arguments!");
|
|
printCmdLineUsage();
|
|
System.exit(1);
|
|
}
|
|
|
|
public static void printHeader(){
|
|
System.out.println(applicationName);
|
|
for(int i=0;i<applicationName.length();i++){
|
|
System.out.print("-");
|
|
}
|
|
System.out.println();
|
|
}
|
|
|
|
public static void printCmdLineUsage(){
|
|
System.out.println("Commandline arguments:");
|
|
System.out.println(" 1) -help | --help | /?");
|
|
System.out.println(" ...shows commandline arguments (this help)");
|
|
System.out.println(" 2) infile");
|
|
System.out.println(" ...opens SWF file with the decompiler GUI");
|
|
System.out.println(" 3) -proxy (-PXXX)");
|
|
System.out.println(" ...auto start proxy in the tray. Optional parameter -P specifies port for proxy. Defaults to 55555. ");
|
|
System.out.println(" 4) -export (as|pcode) outdirectory infile");
|
|
System.out.println(" ...export infile actionscript to outdirectory as AsctionScript code (\"as\" argument) or as PCode (\"pcode\" argument)");
|
|
System.out.println(" 5) -dumpSWF infile");
|
|
System.out.println(" ...dumps list of SWF tags to console");
|
|
System.out.println(" 6) -compress infile outfile");
|
|
System.out.println(" ...Compress SWF infile and save it to outfile");
|
|
System.out.println(" 7) -decompress infile outfile");
|
|
System.out.println(" ...Decompress infile and save it to outfile");
|
|
System.out.println();
|
|
System.out.println("Examples:");
|
|
System.out.println("java -jar ASDec.jar myfile.swf");
|
|
System.out.println("java -jar ASDec.jar -proxy");
|
|
System.out.println("java -jar ASDec.jar -proxy -P1234");
|
|
System.out.println("java -jar ASDec.jar -export as \"C:\\decompiled\\\" myfile.swf");
|
|
System.out.println("java -jar ASDec.jar -export pcode \"C:\\decompiled\\\" myfile.swf");
|
|
System.out.println("java -jar ASDec.jar -dumpSWF myfile.swf");
|
|
System.out.println("java -jar ASDec.jar -compress myfile.swf myfiledec.swf");
|
|
System.out.println("java -jar ASDec.jar -deccompress myfiledec.swf myfile.swf");
|
|
}
|
|
|
|
/**
|
|
* @param args the command line arguments
|
|
*/
|
|
public static void main(String[] args) throws IOException {
|
|
//updateLicenseInDir(new File("src/")); System.exit(0); //For automatic update of lincense in source files
|
|
|
|
View.setWinLookAndFeel();
|
|
loadReplacements();
|
|
if (args.length < 1) {
|
|
showModeFrame();
|
|
} else {
|
|
if (args[0].equals("-proxy")) {
|
|
int port = 55555;
|
|
for (int i = 0; i < args.length; i++) {
|
|
if (args[i].startsWith("-P")) {
|
|
try {
|
|
port = Integer.parseInt(args[i].substring(2));
|
|
} catch (NumberFormatException nex) {
|
|
System.err.println("Bad port number");
|
|
}
|
|
}
|
|
}
|
|
if (proxyFrame == null) proxyFrame = new ProxyFrame();
|
|
proxyFrame.setPort(port);
|
|
addTrayIcon();
|
|
switchProxy();
|
|
}else if (args[0].equals("-export")) {
|
|
if(args.length<4){
|
|
badArguments();
|
|
}
|
|
String exportFormat=args[1];
|
|
if(!exportFormat.toLowerCase().equals("as")){
|
|
if(!exportFormat.toLowerCase().equals("pcode")){
|
|
System.err.println("Invalid export format:"+exportFormat);
|
|
badArguments();
|
|
}
|
|
}
|
|
File outDir=new File(args[2]);
|
|
File inFile=new File(args[3]);
|
|
if(!inFile.exists()){
|
|
System.err.println("Input SWF file does not exist!");
|
|
badArguments();
|
|
}
|
|
commandLineMode=true;
|
|
boolean exportOK=true;
|
|
try{
|
|
printHeader();
|
|
exportOK=exportSWF(inFile.getAbsolutePath(),outDir.getAbsolutePath(),exportFormat.equals("pcode"));
|
|
}catch(Exception ex){
|
|
exportOK=false;
|
|
System.err.print("FAIL: Exporting Failed on Exception - ");
|
|
System.err.println(ex.getLocalizedMessage());
|
|
System.exit(1);
|
|
}
|
|
if(exportOK){
|
|
System.out.println("OK");
|
|
System.exit(0);
|
|
}else{
|
|
System.err.println("FAIL: No ActionScript version 3 found in the input file.");
|
|
System.exit(1);
|
|
}
|
|
} else if (args[0].equals("-compress")) {
|
|
if(args.length<3){
|
|
badArguments();
|
|
}
|
|
|
|
if(SWF.fws2cws(new FileInputStream(args[1]), new FileOutputStream(args[2]))){
|
|
System.out.println("OK");
|
|
}else{
|
|
System.err.println("FAIL");;
|
|
}
|
|
} else if (args[0].equals("-decompress")) {
|
|
if(args.length<3){
|
|
badArguments();
|
|
}
|
|
|
|
if(SWF.cws2fws(new FileInputStream(args[1]), new FileOutputStream(args[2]))){
|
|
System.out.println("OK");
|
|
System.exit(0);
|
|
}else{
|
|
System.err.println("FAIL");
|
|
System.exit(1);
|
|
}
|
|
} else if (args[0].equals("-dumpSWF")) {
|
|
if(args.length<2){
|
|
badArguments();
|
|
}
|
|
try {
|
|
dump_tags=true;
|
|
parseSWF(args[1]);
|
|
} catch (Exception ex) {
|
|
System.err.println("Dump failed due to Exception - "+ex.getLocalizedMessage());
|
|
System.exit(1);
|
|
}
|
|
System.exit(0);
|
|
}else if (args[0].equals("-help")||args[0].equals("--help")||args[0].equals("/?")){
|
|
printHeader();
|
|
printCmdLineUsage();
|
|
System.exit(0);
|
|
}
|
|
else if(args.length==1){
|
|
openFile(args[0]);
|
|
}else{
|
|
badArguments();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public static String tempFile(String url) {
|
|
File f = new File(getASDecHome() + "saved" + File.separator);
|
|
if (!f.exists()) f.mkdirs();
|
|
return getASDecHome() + "saved" + File.separator + "asdec_" + Integer.toHexString(url.hashCode()) + ".tmp";
|
|
|
|
}
|
|
|
|
public static void removeTrayIcon() {
|
|
if (SystemTray.isSupported()) {
|
|
SystemTray tray = SystemTray.getSystemTray();
|
|
if (trayIcon != null) {
|
|
tray.remove(trayIcon);
|
|
trayIcon = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void switchProxy() {
|
|
proxyFrame.switchState();
|
|
if (stopMenuItem != null) {
|
|
if (proxyFrame.isRunning()) {
|
|
stopMenuItem.setLabel("Stop proxy");
|
|
} else {
|
|
stopMenuItem.setLabel("Start proxy");
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void addTrayIcon() {
|
|
if (trayIcon != null) return;
|
|
if (SystemTray.isSupported()) {
|
|
SystemTray tray = SystemTray.getSystemTray();
|
|
trayIcon = new TrayIcon(View.loadImage("com/jpexs/asdec/gui/graphics/proxy16.png"), "JP ASDec Proxy");
|
|
trayIcon.setImageAutoSize(true);
|
|
PopupMenu trayPopup = new PopupMenu();
|
|
|
|
|
|
ActionListener trayListener = new ActionListener() {
|
|
/**
|
|
* Invoked when an action occurs.
|
|
*/
|
|
public void actionPerformed(ActionEvent e) {
|
|
if (e.getActionCommand().equals("EXIT")) Main.exit();
|
|
if (e.getActionCommand().equals("SHOW")) Main.showProxy();
|
|
if (e.getActionCommand().equals("SWITCH")) Main.switchProxy();
|
|
}
|
|
};
|
|
|
|
|
|
MenuItem showMenuItem = new MenuItem("Show proxy");
|
|
showMenuItem.setActionCommand("SHOW");
|
|
showMenuItem.addActionListener(trayListener);
|
|
trayPopup.add(showMenuItem);
|
|
stopMenuItem = new MenuItem("Start proxy");
|
|
stopMenuItem.setActionCommand("SWITCH");
|
|
stopMenuItem.addActionListener(trayListener);
|
|
trayPopup.add(stopMenuItem);
|
|
trayPopup.addSeparator();
|
|
MenuItem exitMenuItem = new MenuItem("Exit");
|
|
exitMenuItem.setActionCommand("EXIT");
|
|
exitMenuItem.addActionListener(trayListener);
|
|
trayPopup.add(exitMenuItem);
|
|
|
|
trayIcon.setPopupMenu(trayPopup);
|
|
trayIcon.addMouseListener(new MouseAdapter() {
|
|
/**
|
|
* {@inheritDoc}
|
|
*/
|
|
@Override
|
|
public void mouseClicked(MouseEvent e) {
|
|
if (e.getButton() == MouseEvent.BUTTON1) {
|
|
Main.showProxy();
|
|
}
|
|
}
|
|
});
|
|
try {
|
|
tray.add(trayIcon);
|
|
} catch (AWTException ex) {
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void exit() {
|
|
saveReplacements();
|
|
System.exit(0);
|
|
}
|
|
|
|
public static void about()
|
|
{
|
|
(new AboutDialog()).setVisible(true);
|
|
}
|
|
}
|