提交 c55ea04e 编写于 作者: M Mathieu Bastian 提交者: Mathieu Bastian

Replace ChangeListener by PropertyChangeListener in ProjectInformation and...

Replace ChangeListener by PropertyChangeListener in ProjectInformation and WorkspaceInformation. Also improve documentation in ProjectAPI.
上级 5888438c
......@@ -87,8 +87,6 @@ public interface ProjectController {
public void closeCurrentWorkspace();
public void cleanWorkspace(Workspace workspace);
public Workspace duplicateWorkspace(Workspace workspace);
public void setSource(Workspace workspace, String source);
......
......@@ -38,37 +38,113 @@ made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
*/
package org.gephi.project.api;
import java.beans.PropertyChangeListener;
import java.io.File;
import javax.swing.event.ChangeListener;
/**
* Hosts various information about a project the module is maintaining.
* Hosts various information about a project.
* <p>
* Clients can subscribe to changes by using the
* {@link #addChangeListener(java.beans.PropertyChangeListener) } method. It
* triggers the following events:
* <ul>
* <li><b>EVENT_OPEN:</b> Project opened
* <li><b>EVENT_CLOSE:</b> Project closed
* <li><b>EVENT_RENAME:</b> Project renamed
* <li><b>EVENT_SET_FILE:</b> Project file set
* </ul>
*
* @author Mathieu Bastian
* @see Project
*/
public interface ProjectInformation {
public static final String EVENT_OPEN = "open";
public static final String EVENT_CLOSE = "close";
public static final String EVENT_RENAME = "rename";
public static final String EVENT_SET_FILE = "setFile";
/**
* Returns true if the project is open.
*
* @return true if open, false otherwise
*/
public boolean isOpen();
/**
* Returns true if the project is closed.
*
* @return true if closed, false otherwise
*/
public boolean isClosed();
/**
* Returns true if the project is invalid.
*
* @return true if invalid, false otherwise
*/
public boolean isInvalid();
/**
* Returns the name of the project.
* <p>
* The name can't be null and has a default value (e.g. Project 1).
*
* @return the project's name
*/
public String getName();
/**
* Returns true if the project is associated with a file.
* <p>
* A project is associated with a file if it has been saved/loaded to/from a
* file.
*
* @return true if associated with a file, false otherwise
*/
public boolean hasFile();
/**
* Returns the filename associated with this project.
* <p>
* Returns an empty string if the project isn't associated with a file.
*
* @see #hasFile()
* @return file name
*/
public String getFileName();
/**
* Returns the file associated with this project.
* <p>
* Returns null if the project isn't associated with a file.
*
* @see #hasFile()
* @return file or null if none
*/
public File getFile();
/**
* Returns the project this information class belongs to.
*
* @return project reference
*/
public Project getProject();
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
/**
* Add change listener.
*
* @param listener change listener
*/
public void addChangeListener(PropertyChangeListener listener);
/**
* Remove change listener.
*
* @param listener change listener
*/
public void removeChangeListener(PropertyChangeListener listener);
}
......@@ -38,30 +38,73 @@ made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
*/
package org.gephi.project.api;
/**
* Hosts user data about a project. These information are usually saved to the
* project file.
* Hosts user data about a project.
* <p>
* These information are also saved to the project file.
*
* @author Mathieu Bastian
*/
public interface ProjectMetaData {
/**
* Returns the keywords of this project.
*
* @return the project's keywords or empty string if missing
*/
public String getKeywords();
/**
* Returns the author of this project.
* <p>
* The default value is the computer's user name.
*
* @return project's author
*/
public String getAuthor();
/**
* Returns the description of this project.
*
* @return the project's description or empty string if missing
*/
public String getDescription();
/**
* Returns the title of this project.
*
* @return the project's title or empty string if missing
*/
public String getTitle();
/**
* Sets the project's author.
*
* @param author author
*/
public void setAuthor(String author);
/**
* Sets the project's description.
*
* @param description description
*/
public void setDescription(String description);
/**
* Sets the project's keywords.
*
* @param keywords keywords
*/
public void setKeywords(String keywords);
/**
* Sets the project's title.
*
* @param title title
*/
public void setTitle(String title);
}
......@@ -38,19 +38,34 @@ made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
*/
package org.gephi.project.api;
/**
* Hosts the project lists and the currently selected project.
*
*
* @author Mathieu Bastian
*/
public interface Projects {
/**
* Returns true if a project is selected.
*
* @return true if current project, false otherwise
*/
public boolean hasCurrentProject();
/**
* Returns the current project or null if missing.
*
* @return current project or null if missing
*/
public Project getCurrentProject();
/**
* Returns an array of all projects.
*
* @return project array
*/
public Project[] getProjects();
}
......@@ -91,15 +91,14 @@ public interface Workspace extends Lookup.Provider {
* storing models in this lookup.
* <p>
* May contains:
* <ol><li><code>GraphModel</code></li>
* <li><code>AttributeModel</code></li>
* <ul><li><code>GraphModel</code></li>
* <li><code>LayoutModel</code></li>
* <li><code>StatisticsModel</code></li>
* <li><code>FiltersModel</code></li>
* <li><code>PreviewModel</code></li>
* <li><code>VizModel</code></li>
* <li>...</li>
* </ol>
* </ul>
*
* @return the workspace's lookup
*/
......
......@@ -41,29 +41,86 @@
*/
package org.gephi.project.api;
import javax.swing.event.ChangeListener;
import java.beans.PropertyChangeListener;
/**
* Hosts various information about a workspace the module is maintaining.
* Hosts various information about a workspace.
* <p>
* Clients can subscribe to changes by using the
* {@link #addChangeListener(java.beans.PropertyChangeListener) } method. It
* triggers the following events:
* <ul>
* <li><b>EVENT_OPEN:</b> Workspace opened
* <li><b>EVENT_CLOSE:</b> Workspace closed
* <li><b>EVENT_RENAME:</b> Workspace renamed
* <li><b>EVENT_SET_SOURCE:</b> Workspace source set
* </ul>
*
* @author Mathieu Bastian
* @see Workspace
*/
public interface WorkspaceInformation {
public static final String EVENT_OPEN = "open";
public static final String EVENT_CLOSE = "close";
public static final String EVENT_RENAME = "rename";
public static final String EVENT_SET_SOURCE = "setSource";
/**
* Returns true if the workspace is open.
*
* @return true if open, false otherwise
*/
public boolean isOpen();
/**
* Returns true if the workspace is closed.
*
* @return true if closed, false otherwise
*/
public boolean isClosed();
/**
* Returns true if the workspace is invalid.
*
* @return true if invalid, false otherwise
*/
public boolean isInvalid();
/**
* Returns the name of the workspace.
* <p>
* The name can't be null and has a default value (e.g. Workspace 1).
*
* @return the workspace's name
*/
public String getName();
/**
* Returns true if the workspace has a source.
*
* @return true if has a source, false otherwise
*/
public boolean hasSource();
/**
* Returns the workspace's source or null if missing.
*
* @return workspace's source or null if missing
*/
public String getSource();
public String getName();
public void addChangeListener(ChangeListener listener);
public void removeChangeListener(ChangeListener listener);
/**
* Add change listener.
*
* @param listener change listener
*/
public void addChangeListener(PropertyChangeListener listener);
/**
* Remove change listener.
*
* @param listener change listener
*/
public void removeChangeListener(PropertyChangeListener listener);
}
......@@ -38,7 +38,7 @@ made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
*/
package org.gephi.project.api;
/**
......@@ -50,25 +50,29 @@ public interface WorkspaceListener {
/**
* Notify a workspace has been created.
*
* @param workspace the workspace that was created
*/
public void initialize(Workspace workspace);
/**
* Notify a workspace has become the selected workspace.
*
* @param workspace the workspace that was made current workspace
*/
public void select(Workspace workspace);
/**
* Notify another workspace will be selected. The <code>select()</code> always
* follows.
* Notify another workspace will be selected. The <code>select()</code>
* always follows.
*
* @param workspace the workspace that is currently the selected workspace
*/
public void unselect(Workspace workspace);
/**
* Notify a workspace will be closed, all data must be destroyed.
*
* @param workspace the workspace that is to be closed
*/
public void close(Workspace workspace);
......
......@@ -49,11 +49,34 @@ package org.gephi.project.api;
*/
public interface WorkspaceProvider {
/**
* Returns the current workspace or null if none.
*
* @return current workspace or null if missing
*/
public Workspace getCurrentWorkspace();
/**
* Returns true if the project has a current workspace.
*
* @return true if has a current workspace, false otherwise
*/
public boolean hasCurrentWorkspace();
/**
* Returns all the workspaces.
* <p>
* Returns an empty array if no workspaces.
*
* @return an array of all workspaces
*/
public Workspace[] getWorkspaces();
/**
* Retrieve a workspace based on its unique identifier.
*
* @param id workspace's unique identifier
* @return found workspace or null if not found
*/
public Workspace getWorkspace(int id);
}
......@@ -41,11 +41,11 @@
*/
package org.gephi.project.impl;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.gephi.project.api.Project;
import org.gephi.project.api.ProjectInformation;
......@@ -65,23 +65,25 @@ public class ProjectInformationImpl implements ProjectInformation {
private Status status = Status.CLOSED;
private File file;
//Event
private final transient List<ChangeListener> listeners;
private final transient List<PropertyChangeListener> listeners;
public ProjectInformationImpl(Project project, String name) {
this.project = project;
this.name = name;
listeners = new ArrayList<ChangeListener>();
listeners = new ArrayList<PropertyChangeListener>();
status = Status.CLOSED;
}
public void open() {
this.status = Status.OPEN;
fireChangeEvent();
Status oldStatus = status;
status = Status.OPEN;
fireChangeEvent(ProjectInformation.EVENT_OPEN, oldStatus, status);
}
public void close() {
this.status = Status.CLOSED;
fireChangeEvent();
Status oldStatus = status;
status = Status.CLOSED;
fireChangeEvent(ProjectInformation.EVENT_CLOSE, oldStatus, status);
}
@Override
......@@ -120,8 +122,9 @@ public class ProjectInformationImpl implements ProjectInformation {
}
public void setName(String name) {
String oldName = this.name;
this.name = name;
fireChangeEvent();
fireChangeEvent(ProjectInformation.EVENT_RENAME, oldName, name);
}
@Override
......@@ -135,25 +138,29 @@ public class ProjectInformationImpl implements ProjectInformation {
}
public void setFile(File file) {
File oldFile = this.file;
this.file = file;
fireChangeEvent();
fireChangeEvent(ProjectInformation.EVENT_SET_FILE, oldFile, file);
}
//EVENTS
@Override
public void addChangeListener(ChangeListener listener) {
public void addChangeListener(PropertyChangeListener listener) {
listeners.add(listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
public void removeChangeListener(PropertyChangeListener listener) {
listeners.remove(listener);
}
public void fireChangeEvent() {
ChangeEvent event = new ChangeEvent(this);
for (ChangeListener listener : listeners) {
listener.stateChanged(event);
public void fireChangeEvent(String eventName, Object oldValue, Object newValue) {
if ((oldValue == null && newValue != null) || (oldValue != null && newValue == null)
|| (oldValue != null && !oldValue.equals(newValue))) {
PropertyChangeEvent event = new PropertyChangeEvent(this, eventName, oldValue, newValue);
for (PropertyChangeListener listener : listeners) {
listener.propertyChange(event);
}
}
}
}
......@@ -46,41 +46,34 @@ import java.io.DataOutputStream;
import org.gephi.project.api.Workspace;
/**
* This class is similar to {@link WorkspacePersistenceProvider} except that it
* allows bytes serialization instead of XML.
*
* @author mbastian
* @author Mathieu Bastian
*/
public interface WorkspaceBytesPersistenceProvider {
/**
* <p>This is automatically called when saving a project file.</p>
* <p>Your implementation must enclose all your data xml in a tag with the
* name provided in your
* <code>getIdentifier</code> method.</p>
* This is automatically called when saving a project file.
*
* @param writer XMLStreamWriter for xml serialization of this persistence
* provider data
* @param workspace Current workspace being serialized
* @param stream DataOutputStream stream to write to
* @param workspace current workspace being serialized
*/
public void writeBytes(DataOutputStream stream, Workspace workspace);
/**
* <p>This is automatically called when a start element with the tag name
* provided in your
* <code>getIdentifier</code> method.</p>
* <p>Your implementation must detect the tag end element to stop
* reading.</p>
* This is automatically called when loading a project file.
*
* @param reader XMLStreamReader for deserialization of this persistence
* provider data previously serialized
* @param workspace Current workspace being deserialized
* @param stream DataInputStream stream to read from
* @param workspace current workspace being deserialized
*/
public void readBytes(DataInputStream stream, Workspace workspace);
/**
* Unique XML tag identifier for your
* <code>WorkspacePersistenceProvider</code>
* Unique tag identifier for your
* <code>WorkspaceBytesPersistenceProvider</code>
*
* @return Unique identifier describing your data
* @return unique identifier describing your data
*/
public String getIdentifier();
}
......@@ -38,12 +38,16 @@ made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
*/
package org.gephi.project.spi;
import org.gephi.project.api.Workspace;
/**
* Interface to implement workspace duplicate providers.
* <p>
* Implementations should take care of duplicating the models they are
* responsible for.
*
* @author Mathieu Bastian
*/
......
......@@ -38,7 +38,7 @@ made subject to such option by the copyright holder.
Contributor(s):
Portions Copyrighted 2011 Gephi Consortium.
*/
*/
package org.gephi.project.spi;
import javax.xml.stream.XMLStreamReader;
......@@ -46,53 +46,68 @@ import javax.xml.stream.XMLStreamWriter;
import org.gephi.project.api.Workspace;
/**
* Interface modules implement to notify the system they can read/write part
* of the .gephi project file to serialize states and data.
* Interface modules implement to notify the system they can read/write part of
* the .gephi project file to serialize states and data.
* <h3>How saving a project works</h3>
* <ol><li>The saving task is looking for all implementations of this interface and
* asks to return an XML element that represents data for each workspace.</li>
* <ol><li>The saving task is looking for all implementations of this interface
* and asks to return an XML element that represents data for each
* workspace.</li>
* <li>All of these elements are written in the .gephi project file.</li></ol>
* <h3>How loading a project works</h3>
* <ol><li>The loading task is looking for all implementations of this interface and
* asks for the identifier returned by <code>getIdentifier()</code>.</li>
* <li>When traversing the gephi project XML document it tries to match markups with
* identifiers. When match, call this provider <code>readXML()</code> method
* with the XML element.</li></ol>
*
* <p>Thus this interface allows any module to serialize and deserialize its data
* <ol><li>The loading task is looking for all implementations of this interface
* and asks for the identifier returned by <code>getIdentifier()</code>.</li>
* <li>When traversing the gephi project XML document it tries to match markups
* with identifiers. When match, call this provider <code>readXML()</code>
* method with the XML element.</li></ol>
*
* <p>
* Thus this interface allows any module to serialize and deserialize its data
* to gephi project files.</p>
*
*
* <p>
* In order to have your <code>WorkspacePersistenceProvider</code> called,
* you must annotate it with <code>@ServiceProvider(service = WorkspacePersistenceProvider.class, position = xy)</code>
* In order to have your <code>WorkspacePersistenceProvider</code> called, you
* must annotate it with
* <code>@ServiceProvider(service = WorkspacePersistenceProvider.class, position = xy)</code>
* </p>
* <p>
* The <code>position</code> parameter is optional but often useful when when you need other <code>WorkspacePersistenceProvider</code> data deserialized before yours.
* The <code>position</code> parameter is optional but often useful when when
* you need other <code>WorkspacePersistenceProvider</code> data deserialized
* before yours.
* </p>
*
*
* @author Mathieu Bastian
* @see Workspace
*/
public interface WorkspacePersistenceProvider {
/**
* <p>This is automatically called when saving a project file.</p>
* <p>Your implementation must enclose all your data xml in a tag with the name provided in your <code>getIdentifier</code> method.</p>
* @param writer XMLStreamWriter for xml serialization of this persistence provider data
* This is automatically called when saving a project file.
* <p>
* Your implementation must enclose all your data xml in a tag with the name
* provided in your <code>getIdentifier</code> method.
*
* @param writer XMLStreamWriter for xml serialization of this persistence
* provider data
* @param workspace Current workspace being serialized
*/
public void writeXML(XMLStreamWriter writer, Workspace workspace);
/**
* <p>This is automatically called when a start element with the tag name provided in your <code>getIdentifier</code> method.</p>
* <p>Your implementation must detect the tag end element to stop reading.</p>
* @param reader XMLStreamReader for deserialization of this persistence provider data previously serialized
* This is automatically called when a start element with the tag name
* provided in your <code>getIdentifier</code> method.
* <p>
* Your implementation must detect the tag end element to stop reading.
*
* @param reader XMLStreamReader for deserialization of this persistence
* provider data previously serialized
* @param workspace Current workspace being deserialized
*/
public void readXML(XMLStreamReader reader, Workspace workspace);
/**
* Unique XML tag identifier for your <code>WorkspacePersistenceProvider</code>
* Unique XML tag identifier for your
* <code>WorkspacePersistenceProvider</code>.
*
* @return Unique identifier describing your data
*/
public String getIdentifier();
......
......@@ -41,10 +41,10 @@
*/
package org.gephi.workspace.impl;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.gephi.project.api.WorkspaceInformation;
/**
......@@ -61,7 +61,7 @@ public class WorkspaceInformationImpl implements WorkspaceInformation {
private Status status = Status.CLOSED;
private String source;
//Lookup
private final transient List<ChangeListener> listeners = new ArrayList<ChangeListener>();
private final transient List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
public WorkspaceInformationImpl(String name) {
this.name = name;
......@@ -82,12 +82,15 @@ public class WorkspaceInformationImpl implements WorkspaceInformation {
}
public void setName(String name) {
String oldValue = this.name;
this.name = name;
fireChangeEvent();
fireChangeEvent(WorkspaceInformation.EVENT_RENAME, oldValue, name);
}
public void setSource(String source) {
String oldValue = this.source;
this.source = source;
fireChangeEvent(WorkspaceInformation.EVENT_SET_SOURCE, oldValue, source);
}
@Override
......@@ -101,13 +104,15 @@ public class WorkspaceInformationImpl implements WorkspaceInformation {
}
public void open() {
this.status = Status.OPEN;
fireChangeEvent();
Status oldValue = status;
status = Status.OPEN;
fireChangeEvent(WorkspaceInformation.EVENT_OPEN, oldValue, status);
}
public void close() {
this.status = Status.CLOSED;
fireChangeEvent();
Status oldValue = status;
status = Status.CLOSED;
fireChangeEvent(WorkspaceInformation.EVENT_CLOSE, oldValue, status);
}
public void invalid() {
......@@ -130,19 +135,22 @@ public class WorkspaceInformationImpl implements WorkspaceInformation {
}
@Override
public void addChangeListener(ChangeListener listener) {
public void addChangeListener(PropertyChangeListener listener) {
listeners.add(listener);
}
@Override
public void removeChangeListener(ChangeListener listener) {
public void removeChangeListener(PropertyChangeListener listener) {
listeners.remove(listener);
}
public void fireChangeEvent() {
ChangeEvent event = new ChangeEvent(this);
for (ChangeListener listener : listeners) {
listener.stateChanged(event);
public void fireChangeEvent(String eventName, Object oldValue, Object newValue) {
if ((oldValue == null && newValue != null) || (oldValue != null && newValue == null)
|| (oldValue != null && !oldValue.equals(newValue))) {
PropertyChangeEvent event = new PropertyChangeEvent(this, eventName, oldValue, newValue);
for (PropertyChangeListener listener : listeners) {
listener.propertyChange(event);
}
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册