/*
* @(#)View.java
*
* Copyright (c) 1996-2010 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 edu.umd.cs.findbugs.annotations.Nullable;
import org.jhotdraw.gui.URIChooser;
import java.io.*;
import java.beans.*;
import java.net.URI;
import javax.swing.*;
/**
* A <em>view</em> paints a document on a {@code JComponent} within an
* {@link Application}.
* <p>
* The document is identified by an {@code URI} (for example a text document
* which is identified by the URI {@code "file://home/readme.txt"}).
* If the same {@code URI} is opened in multiple views, the application sets
* a 'multiple open ID' on the view, so that the user can distinguish between
* the views.
* <p>
* The life of view objects is managed by an application. See the class
* comment of {@link Application} on how to launch an application.
* <p>
* The lifecycle of a view consists of the following steps:
* <ol>
* <li><b>Creation</b><br>
* The application instantiates the view object by calling {@code newInstance()}
* on the class of the view.
* </li>
* <li><b>Initialisation</b><br>
* The application calls the following methods: {@code setActionMap();
* setApplication(); init()}.
* Then it either calls {@code clear()} or {@code read()} on a worker thread.
* </li>
* <li><b>Start</b><br>
* The application adds the component of the view to a container (for example
* a JFrame) and then calls {@code start()}.
* </li>
* <li><b>Activation</b><br>
* When a view becomes the active view of the application, application calls
* {@code activate()}.
* </li>
* <li><b>Deactivation</b><br>
* When a view is not anymore the active view of the application, application
* calls {@code deactivate()}. At a later time, the view may become activated again.
* </li>
* <li><b>Stop</b><br>
* The application calls {@code stop()} on the view and then removes the
* component from its container. At a later time, the view may be started
* again.
* </li>
* <li><b>Dispose</b><br>
* When the view is no longer needed, application calls {@code dispose()} on
* the view, followed by {@code setApplication(null)} and then removes all
* references to it, so that it can be garbage collected.
* </li>
* </ol>
*
* <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}.
* <hr>
*
* @author Werner Randelshofer
* @version $Id$
*/
public interface View extends Disposable {
/**
* The name of the uri property.
*/
public static final String URI_PROPERTY = "uri";
/**
* The name of the application property.
*/
public static final String APPLICATION_PROPERTY = "application";
/**
* The name of the title property.
*/
public static final String TITLE_PROPERTY = "title";
/**
* The name of the enabled property.
*/
public static final String ENABLED_PROPERTY = "enabled";
/**
* The name of the hasUnsavedChanges property.
*/
public static final String HAS_UNSAVED_CHANGES_PROPERTY = "hasUnsavedChanges";
/**
* The name of the multipleOpenId property.
*/
public static final String MULTIPLE_OPEN_ID_PROPERTY = "multipleOpenId";
/**
* The name of the showing property.
*/
public static final String SHOWING_PROPERTY = "showing";
/**
* Gets the application to which this view belongs.
*/
@Nullable public Application getApplication();
/**
* Sets the application of the view.
* By convention, this is only invoked by Application.add() and
* Application.remove().
* This is a bound property.
*/
public void setApplication(@Nullable Application newValue);
/**
* Returns the visual component of the view.
*/
public JComponent getComponent();
/**
* Returns the enabled state of the view.
*/
public boolean isEnabled();
/**
* Sets the enabled state of the view.
*
* The enabled state is used to prevent parallel invocation of actions
* on the view. If an action consists of a sequential part and a
* concurrent part, it must disable the view only for the sequential
* part.
*
* Actions that act on the view must check in their actionPerformed
* method whether the view is enabled.
* If the view is disabled, they must do nothing.
* If the view is enabled, they must disable the view,
* perform the action and then enable the view again.
*
* This is a bound property.
*/
public void setEnabled(boolean newValue);
/**
* Clears the view, for example by emptying the contents of
* the view, or by reading a template contents from a file.
* By convention this method is never invoked on the AWT Event Dispatcher Thread.
* <p>
* This method implements behavior for the following feature:
* <em>Open URI on launch</em>.
* See {@link org.jhotdraw.app}.
*/
public void clear();
/**
* Whether the view is empty. A view is considered empty if the application
* has implicit consent from the user to reuse or destroy the view at any
* time. For example, an application may open an empty view immediately
* after startup. If the user chooses to open a document, the document is
* opened in this view rather than in a new view.
* <p>
* If this method returns true, {@link org.jhotdraw.app.action.file.OpenFileAction}
* and similar actions will open a file in this view, instead of
* opening a new view.
*
* @return True if the view can be reused by open actions.
*/
public boolean isEmpty();
/**
* Returns true, if the view has unsaved changes.
* This is a bound property.
*/
public boolean hasUnsavedChanges();
/**
* Marks all changes as saved.
* This changes the state of hasUnsavedChanges to false.
*/
public void markChangesAsSaved();
/**
* Executes the specified runnable on the worker thread of the view.
* Execution is performed sequentially in the same sequence as the
* runnables have been passed to this method.
* <p>
* Use this method for long running tasks which affect the contents
* of the view as a whole. For example for loading and saving a document.
*/
public void execute(Runnable worker);
/**
* Initializes the view.
* This is invoked right before the application shows the view.
* A view must not consume many resources before method init() is called.
* This is crucial for the responsivenes of an application.
* <p>
* After a view has been initialized using init(),
* either method clear() must be called
* or method read, in order to fully initialize a View.
*/
public void init();
/**
* Starts the view.
* Invoked after a view has been made visible to the user.
* Multiple view can be visible at the same time.
*/
public void start();
/**
* Activates the view.
* This occurs, when the user activated the parent window of the view.
* Only one view can be active at any given time.
* This method is only invoked on a started view.
*/
public void activate();
/**
* Deactivates the view.
* This occurs, when the user closes the view, or activated another view.
* This method is only invoked on a started view.
*/
public void deactivate();
/**
* Stops the view.
* Invoked after a view window has been minimized or made invisible.
*/
public void stop();
/**
* Gets rid of all the resources of the view.
* No other methods should be invoked on the view afterwards.
* A view must not consume many resources after method dispose() has been called.
* This is crucial for the responsivenes of an application.
*/
@Override
public void dispose();
/**
* Gets the action map of the view.
*/
public ActionMap getActionMap();
/**
* Sets the action map for the view.
*/
public void setActionMap(ActionMap m);
/**
* Adds a property change listener.
*/
public void addPropertyChangeListener(PropertyChangeListener l);
/**
* Removes a property change listener.
*/
public void removePropertyChangeListener(PropertyChangeListener l);
/**
* Sets the multiple open id.
* The id is used to help distinguish multiply opened views.
* The id should be displayed in the title of the view.
*/
public void setMultipleOpenId(int newValue);
/**
* Returns the multiple open id.
* If a view is open only once this should be 1.
*/
public int getMultipleOpenId();
/**
* This is used by Application to keep track if a view is showing.
*/
public boolean isShowing();
/**
* This is used by Application to keep track if a view is showing.
*/
public void setShowing(boolean newValue);
/**
* Sets the title of the view.
* <p>
* The title is generated by the application, based on the current
* URI of the view. The application ensures that the title uniquely
* identifies each open view.
* <p>
* The application displays the title in the title bar of the view
* window and in all windows which are associated to the view.
* <p>
* This is a bound property.
*/
public void setTitle(String newValue);
/**
* Gets the title of the view.
*/
public String getTitle();
/**
* Adds a disposable object, which will be disposed when the view
* is disposed.
*
* @param disposable
*/
public void addDisposable(Disposable disposable);
/**
* Removes a disposable object, which was previously added.
*
* @param disposable
*/
public void removeDisposable(Disposable disposable);
/**
* Returns the URI which holds the document of the view.
* <p>
* The URI is used by the <em>Allow multiple views per URI</em> feature.
* See {@link org.jhotdraw.app}.
*/
@Nullable public URI getURI();
/**
* Sets the uri of the view.
* This is a bound property.
*/
public void setURI(@Nullable URI newValue);
/**
* Returns true, if this view can be saved to the specified URI.
* A reason why the view can't be saved to a URI, is that the
* view is unable to write to a file-URI with the given filename
* extension without losing data.
* <p>
* The SaveAction uses this method to decide, whether to display
* a save dialog before saving the URI.
*
* @param uri An URI. If this parameter is null, a NullPointerException
* is thrown.
*/
public boolean canSaveTo(URI uri);
/**
* Writes the view to the specified URI.
* <p>
* By convention this method is never invoked on the AWT Event Dispatcher Thread.
*
* @param uri The location where to write the view.
* @param chooser The chooser which was used for selecting the URI. This
* parameter is null if no chooser was used.
*/
public void write(URI uri, @Nullable URIChooser chooser) throws IOException;
/**
* Reads the view from the specified URI.
* <p>
* By convention this method is never invoked on the AWT Event Dispatcher Thread.
* <p>
* This method implements behavior for the following feature:
* <em>Open URI on launch</em>.
* See {@link org.jhotdraw.app}.
*
* @param uri The location where to write the view.
* @param chooser The chooser which was used for selecting the URI. This
* parameter is null if no chooser was used.
*/
public void read(URI uri, @Nullable URIChooser chooser) throws IOException;
}