org.jcurl.demo.editor.EditorApp.java Source code

Java tutorial

Introduction

Here is the source code for org.jcurl.demo.editor.EditorApp.java

Source

/*
 * jcurl curling simulation framework http://www.jcurl.org
 * Copyright (C) 2005 M. Rohrmoser
 * 
 * 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.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package org.jcurl.demo.editor;

import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JSlider;
import javax.swing.KeyStroke;

import org.apache.commons.logging.Log;
import org.jcurl.core.base.PositionSet;
import org.jcurl.core.base.RockSet;
import org.jcurl.core.base.SpeedSet;
import org.jcurl.core.base.Zoomer;
import org.jcurl.core.helpers.Version;
import org.jcurl.core.io.SetupIO;
import org.jcurl.core.log.JCLoggerFactory;
import org.jcurl.core.swing.AboutDialog;
import org.jcurl.core.swing.JcxFileChooser;
import org.jcurl.core.swing.PngFileChooser;
import org.jcurl.core.swing.PositionDisplay;
import org.jcurl.core.swing.RockEditDisplay;
import org.jcurl.core.swing.SumShotDisplay;
import org.jcurl.core.swing.SumWaitDisplay;
import org.xml.sax.SAXException;

/**
 * A simple editor that brings all together.
 * 
 * @see org.jcurl.core.swing.PositionDisplay
 * @see org.jcurl.demo.editor.LocationController
 * @author <a href="mailto:jcurl@gmx.net">M. Rohrmoser </a>
 * @version $Id:EditorApp.java 378 2007-01-24 01:18:35Z mrohrmoser $
 */
public class EditorApp extends JFrame {

    private static final Cursor Cdefault = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR);

    private static final Cursor Cwait = Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR);

    private static final Log log = JCLoggerFactory.getLogger(EditorApp.class);

    private static final long serialVersionUID = -5330160383513753742L;

    /**
     * @param name
     * @param icon
     * @param executor
     * @param action
     * @return the generated action
     */
    private static AbstractAction createAction(final String name, final Icon icon, final Object executor,
            final String action) {
        return new AbstractAction(name, icon) {

            private static final long serialVersionUID = 1L;

            private Method m = null;

            public void actionPerformed(final ActionEvent evt) {
                if (m == null)
                    try {
                        m = executor.getClass().getMethod(action, null);
                    } catch (Exception e) {
                        try {
                            m = executor.getClass().getDeclaredMethod(action, null);
                        } catch (SecurityException e1) {
                            throw new RuntimeException(e1);
                        } catch (NoSuchMethodException e1) {
                            throw new RuntimeException(e1);
                        }
                    }
                try {
                    m.invoke(executor, null);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }

    public static void main(String[] args) throws SAXException, IOException {
        log.info("Version: " + Version.find());
        final EditorApp frame = new EditorApp();
        frame.cmdNew();
        frame.load(args);
        frame.setVisible(true);
    }

    private JDialog about = null;

    private final JButton bPause;

    private final JButton bStart;

    private final JButton bStop;

    private File currentFile = null;

    private long lastSaved = 0;

    private final RockEditDisplay master;

    private final PositionSet mod_locations = new PositionSet();

    private final SpeedSet mod_speeds = new SpeedSet();

    public EditorApp() {
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                EditorApp.this.cmdExit();
            }
        });
        master = new RockEditDisplay();
        master.setPos(mod_locations);
        master.setSpeed(mod_speeds);
        final PositionDisplay pnl2 = new PositionDisplay();
        pnl2.setPos(mod_locations);
        pnl2.setZoom(Zoomer.HOG2HACK);

        final Container con = getContentPane();

        con.add(master, "Center");
        con.add(new SumWaitDisplay(mod_locations), "West");
        con.add(new SumShotDisplay(mod_locations), "East");
        {
            final Box b0 = Box.createVerticalBox();
            final Box b1 = Box.createHorizontalBox();
            b1.add(Box.createRigidArea(new Dimension(0, 75)));
            b1.add(pnl2);
            b0.add(b1);
            b0.add(new JSlider(0, 100, 0));
            final Box b2 = Box.createHorizontalBox();
            b2.add(Box.createHorizontalGlue());
            b2.add(bStart = this.newButton("Start", this, "cmdRunStart"));
            b2.add(bPause = this.newButton("Pause", this, "cmdRunPause"));
            b2.add(bStop = this.newButton("Stop", this, "cmdRunStop"));
            b2.add(Box.createHorizontalGlue());
            b0.add(b2);
            con.add(b0, "South");
        }
        bStop.getAction().actionPerformed(null);

        setJMenuBar(createMenu());
        refreshTitle();
        this.setSize(900, 400);

        new SpeedController(mod_locations, mod_speeds, master);
        new LocationController(mod_locations, pnl2);
        lastSaved = mod_locations.getLastChanged();
    }

    boolean chooseLoadFile(final File def) {
        final JFileChooser fc = new JcxFileChooser(def);
        if (JFileChooser.APPROVE_OPTION == fc.showOpenDialog(this)) {
            setCurrentFile(fc.getSelectedFile());
            return true;
        }
        return false;
    }

    boolean chooseSaveFile(final File def) {
        final JFileChooser fc = new JcxFileChooser(def);
        if (JFileChooser.APPROVE_OPTION == fc.showSaveDialog(this)) {
            setCurrentFile(fc.getSelectedFile());
            return true;
        }
        return false;
    }

    void cmdAbout() {
        log.info("");
        if (about == null)
            about = new AboutDialog(this);
        about.setVisible(true);
    }

    void cmdExit() {
        if (!discardUnsavedChanges())
            return;
        System.exit(0);
    }

    void cmdExportPng() throws IOException {
        log.debug("-");
        final JFileChooser fc = new PngFileChooser(currentFile);
        if (JFileChooser.APPROVE_OPTION == fc.showSaveDialog(this)) {
            final File dst = fc.getSelectedFile();
            try {
                this.setCursor(Cwait);
                master.exportPng(dst);
            } finally {
                this.setCursor(Cdefault);
            }
        }
    }

    void cmdNew() {
        if (!discardUnsavedChanges())
            return;
        try {
            this.setCursor(Cwait);
            // initial state
            final PositionSet pos = PositionSet.allOut();
            pos.getDark(0).setLocation(0, 5, 0);
            pos.getDark(1).setLocation(0, 0, 0.5);
            pos.getLight(0).setLocation(0.2, 2.5);
            pos.getLight(1).setLocation(1.0, 1.5);
            final SpeedSet speed = new SpeedSet();
            speed.getDark(0).setLocation(0.1, -1.325, 0.75);
            // feed the model
            PositionSet.allOut(mod_locations);
            RockSet.allZero(mod_speeds);
            lastSaved = System.currentTimeMillis();
        } finally {
            this.setCursor(Cdefault);
        }
    }

    void cmdOpen() throws FileNotFoundException, SAXException, IOException {
        if (!discardUnsavedChanges())
            return;
        // try {
        // final FileOpenService fos = (FileOpenService) ServiceManager
        // .lookup("javax.jnlp.BasicService");
        // final FileContents fc = fos.openFileDialog("/home/m", new
        // String[]{".jcx", ".jcz"});
        // if(fc != null)
        // log.info(fc.getName());
        // } catch (UnavailableServiceException e) {
        // throw new RuntimeException("Uncaught exception", e);
        // }
        if (!chooseLoadFile(getCurrentFile() == null ? new File(".") : getCurrentFile()))
            return;
        SetupIO.load(getCurrentFile(), mod_locations, mod_speeds, null, null);
        lastSaved = System.currentTimeMillis();
    }

    void cmdRunPause() {
        JOptionPane.showMessageDialog(this, "Not implemented yet");
        bStart.getAction().setEnabled(true);
        bPause.getAction().setEnabled(false);
        bStop.getAction().setEnabled(false);
    }

    void cmdRunStart() {
        JOptionPane.showMessageDialog(this, "Not implemented yet");
        bStart.getAction().setEnabled(false);
        bPause.getAction().setEnabled(true);
        bStop.getAction().setEnabled(true);
    }

    void cmdRunStop() {
        bStart.getAction().setEnabled(true);
        bPause.getAction().setEnabled(false);
        bStop.getAction().setEnabled(false);
    }

    void cmdSave() throws SAXException, IOException {
        if (getCurrentFile() == null)
            if (!chooseSaveFile(new File(".")))
                return;
        save(getCurrentFile());
    }

    void cmdSaveAs() throws SAXException, IOException {
        if (!chooseSaveFile(getCurrentFile() == null ? new File(".") : getCurrentFile()))
            return;
        save(getCurrentFile());
    }

    void cmdZoom() {
        log.info("");
    }

    private JMenuBar createMenu() {
        final JMenuBar bar = new JMenuBar();
        {
            final JMenu menu = bar.add(new JMenu("File"));
            menu.setMnemonic('F');
            menu.add(this.newMI("New", null, 'N', -1, this, "cmdNew"));
            menu.add(this.newMI("Open", null, 'O', KeyEvent.VK_O, this, "cmdOpen"));
            menu.addSeparator();
            menu.add(this.newMI("Export Png", null, 'P', KeyEvent.VK_E, this, "cmdExportPng"));
            menu.addSeparator();
            menu.add(this.newMI("Save", null, 'S', KeyEvent.VK_S, this, "cmdSave"));
            menu.add(this.newMI("Save As", null, 'A', -1, this, "cmdSaveAs"));
            menu.addSeparator();
            menu.add(this.newMI("Exit", null, 'x', -1, this, "cmdExit"));
        }
        {
            final JMenu menu = bar.add(new JMenu("View"));
            menu.setMnemonic('V');
            menu.add(this.newMI("Zoom", null, 'z', -1, this, "cmdZoom"));
        }
        {
            final JMenu menu = bar.add(new JMenu("Play"));
            menu.setMnemonic('P');
            menu.add(this.newMI('a', -1, bStart.getAction()));
            menu.add(this.newMI('P', -1, bPause.getAction()));
            menu.add(this.newMI('o', -1, bStop.getAction()));
        }
        {
            final JMenu menu = bar.add(new JMenu("Help"));
            menu.setMnemonic('H');
            menu.add(this.newMI("About", null, 'a', -1, this, "cmdAbout"));
        }
        return bar;
    }

    private boolean discardUnsavedChanges() {
        if (mod_locations.getLastChanged() <= lastSaved && mod_speeds.getLastChanged() <= lastSaved)
            return true;
        if (JOptionPane.YES_OPTION == JOptionPane.showConfirmDialog(this, "Discard unsaved changes?", "Warning",
                JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE))
            return true;
        return false;
    }

    public File getCurrentFile() {
        return currentFile;
    }

    private void load(final File f, final PositionSet pos) throws FileNotFoundException, SAXException, IOException {
        SetupIO.load(f, pos, null, null, null);
    }

    private void load(final String[] args) throws SAXException, IOException {
        if (args.length <= 0)
            return;
        final File f = new File(args[0]);
        if (!f.exists())
            return;
        this.load(f, mod_locations);
    }

    private JButton newButton(final Action action) {
        final JButton item = new JButton(action);
        // item.setMnemonic(mnemonic);
        // if (ctrlAccel >= 0)
        // item.setAccelerator(KeyStroke.getKeyStroke(ctrlAccel,
        // InputEvent.CTRL_MASK));
        return item;
    }

    private JButton newButton(final String name, final Object executor, final String action) {
        return this.newButton(createAction(name, null, executor, action));
    }

    private JMenuItem newMI(final char mnemonic, final int ctrlAccel, final Action action) {
        final JMenuItem item = new JMenuItem(action);
        item.setMnemonic(mnemonic);
        if (ctrlAccel >= 0)
            item.setAccelerator(KeyStroke.getKeyStroke(ctrlAccel, InputEvent.CTRL_MASK));
        return item;
    }

    private JMenuItem newMI(final String name, final Icon icon, final char mnemonic, final int ctrlAccel,
            final Object executor, final String action) {
        return this.newMI(mnemonic, ctrlAccel, createAction(name, icon, executor, action));
    }

    private void refreshTitle() {
        setTitle(getClass().getName() + " - " + (currentFile == null ? "" : currentFile.getAbsolutePath()));
    }

    private void save(File f) throws SAXException, IOException {
        SetupIO.save(f, mod_locations, mod_speeds, null, null);
        lastSaved = System.currentTimeMillis();
        refreshTitle();
    }

    public void setCurrentFile(File currentFile) {
        if (currentFile == null || currentFile.getName().endsWith(".jcx") || currentFile.getName().endsWith(".jcz"))
            this.currentFile = currentFile;
        else
            this.currentFile = new File(currentFile.getName() + ".jcx");
        refreshTitle();
    }
}