/* Launch4j (http://launch4j.sourceforge.net/) Cross-platform Java application wrapper for creating Windows native executables. Copyright (C) 2004, 2006 Grzegorz Kowal 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 2 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, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Created on 2005-05-09 */ package net.sf.launch4j.formimpl; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JToolBar; import javax.swing.UIManager; import com.jgoodies.plaf.Options; import com.jgoodies.plaf.plastic.PlasticXPLookAndFeel; import foxtrot.Task; import foxtrot.Worker; import net.sf.launch4j.Builder; import net.sf.launch4j.BuilderException; import net.sf.launch4j.ExecException; import net.sf.launch4j.FileChooserFilter; import net.sf.launch4j.Log; import net.sf.launch4j.Main; import net.sf.launch4j.Util; import net.sf.launch4j.binding.BindingException; import net.sf.launch4j.binding.InvariantViolationException; import net.sf.launch4j.config.Config; import net.sf.launch4j.config.ConfigPersister; import net.sf.launch4j.config.ConfigPersisterException; /** * @author Copyright (C) 2005 Grzegorz Kowal */ public class MainFrame extends JFrame { private static MainFrame _instance; private final JToolBar _toolBar; private final JButton _runButton; private final ConfigFormImpl _configForm; private final JFileChooser _fileChooser = new JFileChooser(); private File _outfile; private boolean _saved = false; public static void createInstance() { try { Toolkit.getDefaultToolkit().setDynamicLayout(true); System.setProperty("sun.awt.noerasebackground","true"); //$NON-NLS-1$ //$NON-NLS-2$ // JGoodies Options.setDefaultIconSize(new Dimension(16, 16)); // menu icons Options.setUseNarrowButtons(false); Options.setPopupDropShadowEnabled(true); UIManager.setLookAndFeel(new PlasticXPLookAndFeel()); _instance = new MainFrame(); } catch (Exception e) { System.err.println(e); } } public static MainFrame getInstance() { return _instance; } public MainFrame() { showConfigName(null); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); addWindowListener(new MainFrameListener()); setGlassPane(new GlassPane(this)); _fileChooser.setFileFilter(new FileChooserFilter( Messages.getString("MainFrame.config.files"), //$NON-NLS-1$ new String[] {".xml", ".cfg"})); //$NON-NLS-1$ //$NON-NLS-2$ _toolBar = new JToolBar(); _toolBar.setFloatable(false); _toolBar.setRollover(true); addButton("images/new.png", //$NON-NLS-1$ Messages.getString("MainFrame.new.config"), //$NON-NLS-1$ new NewActionListener()); addButton("images/open.png", //$NON-NLS-1$ Messages.getString("MainFrame.open.config"), //$NON-NLS-1$ new OpenActionListener()); addButton("images/save.png", //$NON-NLS-1$ Messages.getString("MainFrame.save.config"), //$NON-NLS-1$ new SaveActionListener()); _toolBar.addSeparator(); addButton("images/build.png", //$NON-NLS-1$ Messages.getString("MainFrame.build.wrapper"), //$NON-NLS-1$ new BuildActionListener()); _runButton = addButton("images/run.png", //$NON-NLS-1$ Messages.getString("MainFrame.test.wrapper"), //$NON-NLS-1$ new RunActionListener()); setRunEnabled(false); _toolBar.addSeparator(); addButton("images/info.png", //$NON-NLS-1$ Messages.getString("MainFrame.about.launch4j"), //$NON-NLS-1$ new AboutActionListener()); _configForm = new ConfigFormImpl(); getContentPane().setLayout(new BorderLayout()); getContentPane().add(_toolBar, BorderLayout.NORTH); getContentPane().add(_configForm, BorderLayout.CENTER); pack(); Dimension scr = Toolkit.getDefaultToolkit().getScreenSize(); Dimension fr = getSize(); fr.height += 100; setBounds((scr.width - fr.width) / 2, (scr.height - fr.height) / 2, fr.width, fr.height); setVisible(true); } private JButton addButton(String iconPath, String tooltip, ActionListener l) { ImageIcon icon = new ImageIcon(MainFrame.class.getClassLoader().getResource(iconPath)); JButton b = new JButton(icon); b.setToolTipText(tooltip); b.addActionListener(l); _toolBar.add(b); return b; } public void info(String text) { JOptionPane.showMessageDialog(this, text, Main.PROGRAM_NAME, JOptionPane.INFORMATION_MESSAGE); } public void warn(String text) { JOptionPane.showMessageDialog(this, text, Main.PROGRAM_NAME, JOptionPane.WARNING_MESSAGE); } public void warn(InvariantViolationException e) { e.getBinding().markInvalid(); warn(e.getMessage()); e.getBinding().markValid(); } private boolean isModified() { return (!_configForm.isModified()) || JOptionPane.showConfirmDialog(MainFrame.this, Messages.getString("MainFrame.discard.changes"), //$NON-NLS-1$ Messages.getString("MainFrame.confirm"), //$NON-NLS-1$ JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION; } private boolean save() { // XXX try { _configForm.get(ConfigPersister.getInstance().getConfig()); if (_fileChooser.showSaveDialog(MainFrame.this) == JOptionPane.YES_OPTION) { File f = _fileChooser.getSelectedFile(); if (!f.getPath().endsWith(".xml")) { //$NON-NLS-1$ f = new File(f.getPath() + ".xml"); //$NON-NLS-1$ } ConfigPersister.getInstance().save(f); _saved = true; showConfigName(f); return true; } return false; } catch (InvariantViolationException ex) { warn(ex); return false; } catch (BindingException ex) { warn(ex.getMessage()); return false; } catch (ConfigPersisterException ex) { warn(ex.getMessage()); return false; } } private void showConfigName(File config) { setTitle(Main.PROGRAM_NAME + " - " //$NON-NLS-1$ + (config != null ? config.getName() : Messages.getString("MainFrame.untitled"))); //$NON-NLS-1$ } private void setRunEnabled(boolean enabled) { if (!enabled) { _outfile = null; } _runButton.setEnabled(enabled); } private void clearConfig() { ConfigPersister.getInstance().createBlank(); _configForm.clear(ConfigPersister.getInstance().getConfig()); } private class MainFrameListener extends WindowAdapter { public void windowOpened(WindowEvent e) { clearConfig(); } public void windowClosing(WindowEvent e) { if (isModified()) { System.exit(0); } } } private class NewActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { if (isModified()) { clearConfig(); } _saved = false; showConfigName(null); setRunEnabled(false); } } private class OpenActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { try { if (isModified() && _fileChooser.showOpenDialog(MainFrame.this) == JOptionPane.YES_OPTION) { final File f = _fileChooser.getSelectedFile(); if (f.getPath().endsWith(".xml")) { //$NON-NLS-1$ ConfigPersister.getInstance().load(f); _saved = true; } else { ConfigPersister.getInstance().loadVersion1(f); _saved = false; } _configForm.put(ConfigPersister.getInstance().getConfig()); showConfigName(f); setRunEnabled(false); } } catch (ConfigPersisterException ex) { warn(ex.getMessage()); } } } private class SaveActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { save(); } } private class BuildActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { final Log log = Log.getSwingLog(_configForm.getLogTextArea()); try { if ((!_saved || _configForm.isModified()) && !save()) { return; } log.clear(); ConfigPersister.getInstance().getConfig().checkInvariants(); Builder b = new Builder(log); _outfile = b.build(); setRunEnabled(ConfigPersister.getInstance().getConfig() .getHeaderType() == Config.GUI_HEADER // TODO fix console app test && (Util.WINDOWS_OS || !ConfigPersister.getInstance() .getConfig().isDontWrapJar())); } catch (InvariantViolationException ex) { setRunEnabled(false); ex.setBinding(_configForm.getBinding(ex.getProperty())); // XXX warn(ex); } catch (BuilderException ex) { setRunEnabled(false); log.append(ex.getMessage()); } } } private class RunActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { try { getGlassPane().setVisible(true); Worker.post(new Task() { public Object run() throws ExecException { Log log = Log.getSwingLog(_configForm.getLogTextArea()); log.clear(); String path = _outfile.getPath(); if (Util.WINDOWS_OS) { log.append(Messages.getString("MainFrame.executing") + path); //$NON-NLS-1$ Util.exec(path, log); } else { log.append(Messages.getString("MainFrame.jar.integrity.test") + path); //$NON-NLS-1$ Util.exec("java -jar " + path, log); //$NON-NLS-1$ } return null; } }); } catch (Exception ex) { // XXX errors logged by exec } finally { getGlassPane().setVisible(false); } }; } private class AboutActionListener implements ActionListener { public void actionPerformed(ActionEvent e) { info(Main.PROGRAM_DESCRIPTION + "The following projects are used by launch4j...\n\n" //$NON-NLS-1$ + "MinGW binutils (http://www.mingw.org/)\n" //$NON-NLS-1$ + "Commons BeanUtils (http://jakarta.apache.org/commons/beanutils/)\n" //$NON-NLS-1$ + "Commons Logging (http://jakarta.apache.org/commons/logging/)\n" //$NON-NLS-1$ + "XStream (http://xstream.codehaus.org/)\n" //$NON-NLS-1$ + "JGoodies Forms (http://www.jgoodies.com/freeware/forms/)\n" //$NON-NLS-1$ + "JGoodies Looks (http://www.jgoodies.com/freeware/looks/)\n" //$NON-NLS-1$ + "Foxtrot (http://foxtrot.sourceforge.net/)\n" //$NON-NLS-1$ + "Nuvola Icon Theme (http://www.icon-king.com)"); //$NON-NLS-1$ } } }