/* * @(#)Application.java * * Copyright (c) 1996-2011 The authors and contributors of JHotDraw. * You may not use, copy or modify this file, except in compliance with the * accompanying license terms. */ package org.jhotdraw.app; import javax.annotation.Nullable; import java.awt.Component; import java.awt.Window; import java.beans.PropertyChangeListener; import java.net.URI; import java.util.Collection; import java.util.List; import javax.swing.ActionMap; import javax.swing.JMenu; import org.jhotdraw.gui.URIChooser; /** * An <em>application</em> handles the lifecycle of {@link View} objects and * provides windows to present them on screen. * <p> * An application owns a {@link ApplicationModel} which provides meta-data about * the application, actions and factory methods for creating the views. * <p> * Depending on the document interface style used by the application, an * application can handle multiple views at the same time, or only one. * <p> * Typical document interface styles are the Single Document Interface (SDI), * the Multiple Document Interface (MDI) and the Mac OS X Application Interface * (OSX). Typically, for each of these styles an implementation of * {@code Application} exists. * <p> * Some applications have to decorate all opened windows and dialogs with * user interface elements and special behaviors. To make this work, * it is essential that all code which opens JFrame's, JDialog's or * JWindow's calls the addWindow/Palette and removeWindow/Palette methods on * the application object. * <p> * Unless stated otherwise all methods must be called from the AWT Event * Dispatcher Thread. * <p> * Typical usage of this class: * <pre> * public class MyMainClass { * public static void main(String[] args) { * Application app = new SDIApplication(); // or OSXApplication(), MDIApplication(). * DefaultApplicationModel model = new DefaultApplicationModel(); * model.setName("MyApplication"); * model.setVersion("1.0"); * model.setCopyright("Copyright 2006 (c) Werner Randelshofer. All Rights Reserved."); * model.setViewClassName("org.jhotdraw.myapplication.MyView"); * app.setModel(model); * app.launch(args); * } * </pre> * <hr> * <b>Features</b> * * <p><em>Open last URI on launch</em><br> * When the application is launched, it opens the last opened URI in a view.<br> * {@code Application} also provides an API for data suppliers in {@link #addRecentURI}, * {@link #getRecentURIs}, {@link #clearRecentURIs}.<br> * See {@link org.jhotdraw.app} for a description of the feature. * </p> * * <hr> * <b>Design Patterns</b> * * <p><em>Framework</em><br> * The interfaces and classes listed below together with the {@code Action} * classes in the org.jhotddraw.app.action package define the contracts of a * framework for document oriented applications:<br> * Contract: {@link Application}, {@link ApplicationModel}, {@link View}. * * <p><em>Abstract Factory</em><br> * {@code MenuBuilder} is used by {@code Application} for creating menu items. * The {@code MenuBuilder} is provided by {@code ApplicationModel}.<br> * Abstract Factory: {@link MenuBuilder}<br> * Client: {@link Application}. * <hr> * * @author Werner Randelshofer * @version $Id$ */ public interface Application { /** * The property name of the activeView property. */ public static final String ACTIVE_VIEW_PROPERTY = "activeView"; /** * The property name of the recentURIs property. */ public static final String RECENT_URIS_PROPERTY = "recentURIs"; /** * Launches the application from the main method. * <p> * This method must be called from the main thread of the application. * <p> * Implementations of this method must invoke {@code configure()} on the * current thread and then {@code init(); applicationModel.initApplication(this); * start();} on the AWT Event Dispatcher Thread. * <p> * The launch method determines which URI's it wants to supply to the start() * method. Typically, if URI's have been passed in the {@code args} * parameter, they are passed on to the start() method. Otherwise, if the * property {@code openLastURIOnLaunch} of the application model is true, * the last opened URI is passed to the start method. * <p> * This method implements behavior for the following features: * <em>Launch application</em>, <em>Open last URI on launch</em>. * See {@link org.jhotdraw.app}. * @param args The arguments of the main method */ public void launch(String[] args); /** * Configures the application using the provided arguments array. * <p> * This method must be called from the main thread of the application. * <p> * This method implements behavior for the following feature: * <em>Open URIs from command line on launch</em>. * See {@link org.jhotdraw.app}. * @param args The arguments of the main method */ public void configure(String[] args); /** * Initializes the application. * <p> * By convention this method is only called after {@link #configure} has * been called. * <p> * Typically in this method, the Application sets property name identifier * for application-specific properties in {@code ResourceBundleUtil}. * For example with {@code ResourceBundleUtil.putPropertyNameModifier("os", "mac", "default");} */ public void init(); /** * Starts the application. * <p> * This method creates a view for each supplied URI, and adds it to the application. * If no URI has been supplied, this method may open an empty view. * <p> * By convention this method is only called after {@link #init} has * been called. * <p> * This method implements behavior for the following feature: * <em>Open URI on launch</em>. * See {@link org.jhotdraw.app}. * * @param uris Upon launch, the application may be requested to open views * for a given list of URI's. */ public void start(List<URI> uris); /** * Stops the application without saving any unsaved views. * <p> * By convention this method is only called after {@link #init} has * been called. * <p> * This method must be called from AWT Event Dispatcher Thread. */ public void stop(); /** * Stops the application and then calls System.exit(0). * <p> * By convention this method is only called after {@link #init} has * been called. * <p> * This method must be called from AWT Event Dispatcher Thread. */ public void destroy(); /** * Creates a new view for this application and initializes it, by calling * {@link View#init}. * The view has not been added to the application yet. * To make the view usable with this application, call {@link #add(View)}. * To make it visible, first call {@code add(View)}, then {@link #show(View)}. * @return the created view */ public View createView(); /** * Adds a view to this application. * Fires a "documentCount" property change event. * Invokes method setApplication(this) on the view object. * @param v the view */ public void add(View v); /** * Removes a view from this application and removes it from the users * view. * Fires a "documentCount" property change event. * Invokes method setApplication(null) on the view object. * @param v the view */ public void remove(View v); /** * Shows a view. * @param v the view */ public void show(View v); /** * Hides a view. * @param v the view */ public void hide(View v); /** * This is a convenience method for removing a view and disposing it. * @param v the view */ public void dispose(View v); /** * Returns a read only collection view of the views of this application. * @return the views */ public Collection<View> views(); /** * Returns the active view. This is used for OSXApplication and * MDIApplication which share actions among multiple View instances. * Active view may be become null, if the * application has no view. * <p> * This is a bound property. * @return the active view or null */ @Nullable public View getActiveView(); /** * Returns the enabled state of the application. * @return the value */ public boolean isEnabled(); /** * Sets the enabled state of the application. * * The enabled state is used to prevent parallel invocation of actions * on the application. If an action consists of a sequential part and a * concurrent part, it must disable the application only for the sequential * part. * * Actions that act on the application must check in their actionPerformed * method whether the application is enabled. * If the application is disabled, they must do nothing. * If the application is enabled, they must disable the application, * perform the action and then enable the application again. * * This is a bound property. * @param newValue the value */ public void setEnabled(boolean newValue); /** * Adds a property change listener. * @param l the listener */ public void addPropertyChangeListener(PropertyChangeListener l); /** * Removes a property change listener. * @param l the listener */ public void removePropertyChangeListener(PropertyChangeListener l); /** * Returns the name of the application. * @return the value */ public String getName(); /** * Returns the version of the application. * @return the value */ public String getVersion(); /** * Returns the copyright of the application. * @return the value */ public String getCopyright(); /** * Sets the application model. * @param newValue the value */ public void setModel(ApplicationModel newValue); /** * Returns the application model. * @return the value */ public ApplicationModel getModel(); /** * Returns true, if this application shares tools among multiple views. * @return the value */ public boolean isSharingToolsAmongViews(); /** * Returns the application component. * This may return null, if the application is not represented by a component * of its own on the user interface. * @return the value */ @Nullable public Component getComponent(); /** * Adds a palette window to the application. * @param palette the palette */ public void addPalette(Window palette); /** * Removes a palette window from the application. * @param palette the palette */ public void removePalette(Window palette); /** * Adds a (non-palette) window to the application. * * @param window The window. * @param view The View to which this window is associated, or null * if the window is associated to the application. */ public void addWindow(Window window, @Nullable View view); /** * Removes a (non-palette) window from the application. * @param window the window */ public void removeWindow(Window window); /** * Returns the recently opened URIs. By convention, this is an unmodifiable list. * The first item in the list is the most recently opened URI. * <p> * The most recent URI is used by the <em>Open last URI on launch</em> feature. * See {@link org.jhotdraw.app}. * @return the recently opened URIs */ public java.util.List<URI> getRecentURIs(); /** * Adds an URI to the start of the list of recent URIs. * <p> * This fires a property change event for the property "recentURIs". * <p> * The recent URIs are persisted (for example using the Java Preferences API) * so that they are available on the next launch of the application. * <p> * The most recent URI is used by the <em>Open last URI on launch</em> feature. * See {@link org.jhotdraw.app}. * @param uri the value */ public void addRecentURI(URI uri); /** * Clears the list of recent URIs. * This fires a property change event for the property "recentURIs". * <p> * The recent URIs are persisted (for example using the Java Preferences API) * so that they are available on the next launch of the application. * <p> * The most recent URI is used by the <em>Open last URI on launch</em> feature. * See {@link org.jhotdraw.app}. */ public void clearRecentURIs(); /** * Creates a file menu for the specified view or for the entire application. * * @param v A view or null. * @return A JMenu or null, if the menu is empty. */ @Nullable public JMenu createFileMenu(@Nullable View v); /** * Creates an edit menu for the specified view or for the entire application. * * @param v A view or null. * @return A JMenu or null, if the menu is empty. */ @Nullable public JMenu createEditMenu(@Nullable View v); /** * Creates a view menu for the specified view or for the entire application. * * @param v A view or null. * @return A JMenu or null, if the menu is empty. */ @Nullable public JMenu createViewMenu(@Nullable View v); /** * Creates a window menu for the specified view or for the entire application. * * @param v A view or null. * @return A JMenu or null, if the menu is empty. */ @Nullable public JMenu createWindowMenu(@Nullable View v); /** * Creates a help menu for the specified view of for the entire application. * * @param v A view or null. * @return A JMenu or null, if the menu is empty. */ @Nullable public JMenu createHelpMenu(@Nullable View v); /** * Gets an open chooser for the specified view or for the entire application. * * @param v A view or null. * @return A chooser. */ public URIChooser getOpenChooser(@Nullable View v); /** * Gets a save chooser for the specified view or for the entire application. * * @param v A view or null. * @return A chooser. */ public URIChooser getSaveChooser(@Nullable View v); /** * Gets an export chooser for the specified view or for the entire application. * * @param v A view or null. * @return A chooser. */ public URIChooser getExportChooser(@Nullable View v); /** * Gets an import chooser for the specified view or for the entire application. * * @param v A view or null. * @return A chooser. */ public URIChooser getImportChooser(@Nullable View v); /** * Gets an action map for the specified view or for the entire application. * * @param v A view or null * @return the action map */ public ActionMap getActionMap(@Nullable View v); /** Returns an unmodifiable list of all views of the application. * <p> * The list of views is used by the <em>Allow multiple views per URI</em> feature. * See {@link org.jhotdraw.app}. * @return the views */ public List<View> getViews(); }