diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectController.java b/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectController.java index 8dd4b263dd39125a599ef0e79fccc3c6c429ab9a..08ee9d0aca3c1989d92f7ee2d7af5301b714039e 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectController.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectController.java @@ -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); diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectInformation.java b/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectInformation.java index 5567ef68968795f4fb63e7e2104b5b777731880b..e8f7132db13c80232e4a9533170ab56e8976bdbe 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectInformation.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectInformation.java @@ -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. + *

+ * Clients can subscribe to changes by using the + * {@link #addChangeListener(java.beans.PropertyChangeListener) } method. It + * triggers the following events: + *

* * @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. + *

+ * 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. + *

+ * 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. + *

+ * 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. + *

+ * 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); } diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectMetaData.java b/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectMetaData.java index 40def20150d1dfbd1d29733f84f06e54551c1d6c..8c0d8499a4cb10f1d0aa3884a44c11fab39d1f5d 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectMetaData.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/api/ProjectMetaData.java @@ -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. + *

+ * 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. + *

+ * 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); } diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/api/Projects.java b/modules/ProjectAPI/src/main/java/org/gephi/project/api/Projects.java index 134eb870f1c58679d0681176455ea39d23215c87..b3049b5aa7a30517e450a6729b250c96ce9d2993 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/api/Projects.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/api/Projects.java @@ -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(); } diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/api/Workspace.java b/modules/ProjectAPI/src/main/java/org/gephi/project/api/Workspace.java index c216c211b7af30946bd72367864bda1c48da7a4c..798f515b8c39a29e5215c807a31b8b12e3fde45a 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/api/Workspace.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/api/Workspace.java @@ -91,15 +91,14 @@ public interface Workspace extends Lookup.Provider { * storing models in this lookup. *

* May contains: - *

  1. GraphModel
  2. - *
  3. AttributeModel
  4. + *
+ * * * @return the workspace's lookup */ diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceInformation.java b/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceInformation.java index 73fc39872cbe354a32c524bc15592f6cef255899..5503fc3df478ea8a7ebe7e97320bed179d669839 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceInformation.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceInformation.java @@ -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. + *

+ * Clients can subscribe to changes by using the + * {@link #addChangeListener(java.beans.PropertyChangeListener) } method. It + * triggers the following events: + *

* * @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. + *

+ * 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); } diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceListener.java b/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceListener.java index 21d0d6a53accd3f1bd07d966f9d064cc2aa07ca3..ce77ae9697859dee4cf33ae4a54071b8fd8f5325 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceListener.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceListener.java @@ -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 select() always - * follows. + * Notify another workspace will be selected. The select() + * 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); diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceProvider.java b/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceProvider.java index 5c8d5e1708f125635939eea93ca436d49e6d237c..53e1eb44b39b19cde4af881e68fce4d09f683b02 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceProvider.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/api/WorkspaceProvider.java @@ -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. + *

+ * 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); } diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/impl/ProjectInformationImpl.java b/modules/ProjectAPI/src/main/java/org/gephi/project/impl/ProjectInformationImpl.java index 98787bc34a14cc34c8c5f1c9b026aefb0373bdf9..d3e05aab2a3e1fc5ff543ffbcce4cbea883a40ce 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/impl/ProjectInformationImpl.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/impl/ProjectInformationImpl.java @@ -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 listeners; + private final transient List listeners; public ProjectInformationImpl(Project project, String name) { this.project = project; this.name = name; - listeners = new ArrayList(); + listeners = new ArrayList(); 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); + } } } } diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspaceBytesPersistenceProvider.java b/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspaceBytesPersistenceProvider.java index aef590348f6a20a1ad01717b696f42419b7209d8..7c3b1e4933fbd36156f10090ee8ec770fdc1de19 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspaceBytesPersistenceProvider.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspaceBytesPersistenceProvider.java @@ -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 { /** - *

This is automatically called when saving a project file.

- *

Your implementation must enclose all your data xml in a tag with the - * name provided in your - * getIdentifier method.

+ * 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); /** - *

This is automatically called when a start element with the tag name - * provided in your - * getIdentifier method.

- *

Your implementation must detect the tag end element to stop - * reading.

+ * 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 - * WorkspacePersistenceProvider + * Unique tag identifier for your + * WorkspaceBytesPersistenceProvider * - * @return Unique identifier describing your data + * @return unique identifier describing your data */ public String getIdentifier(); } diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspaceDuplicateProvider.java b/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspaceDuplicateProvider.java index f79c88fed498f397d314a34b7286d46a07de952f..dad303a267e93768fc47ed49732d2209653eebee 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspaceDuplicateProvider.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspaceDuplicateProvider.java @@ -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. + *

+ * Implementations should take care of duplicating the models they are + * responsible for. * * @author Mathieu Bastian */ diff --git a/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspacePersistenceProvider.java b/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspacePersistenceProvider.java index 91724177708a08d186356a88a6eb94b01ae7c9d1..6e2167736c31ebec920f472b56374fadee8e53e1 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspacePersistenceProvider.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/project/spi/WorkspacePersistenceProvider.java @@ -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. *

How saving a project works

- *
  1. The saving task is looking for all implementations of this interface and - * asks to return an XML element that represents data for each workspace.
  2. + *
    1. The saving task is looking for all implementations of this interface + * and asks to return an XML element that represents data for each + * workspace.
    2. *
    3. All of these elements are written in the .gephi project file.
    *

    How loading a project works

    - *
    1. The loading task is looking for all implementations of this interface and - * asks for the identifier returned by getIdentifier().
    2. - *
    3. When traversing the gephi project XML document it tries to match markups with - * identifiers. When match, call this provider readXML() method - * with the XML element.
    - * - *

    Thus this interface allows any module to serialize and deserialize its data + *

    1. The loading task is looking for all implementations of this interface + * and asks for the identifier returned by getIdentifier().
    2. + *
    3. When traversing the gephi project XML document it tries to match markups + * with identifiers. When match, call this provider readXML() + * method with the XML element.
    + * + *

    + * Thus this interface allows any module to serialize and deserialize its data * to gephi project files.

    - * + * *

    - * In order to have your WorkspacePersistenceProvider called, - * you must annotate it with @ServiceProvider(service = WorkspacePersistenceProvider.class, position = xy) + * In order to have your WorkspacePersistenceProvider called, you + * must annotate it with + * @ServiceProvider(service = WorkspacePersistenceProvider.class, position = xy) *

    *

    - * The position parameter is optional but often useful when when you need other WorkspacePersistenceProvider data deserialized before yours. + * The position parameter is optional but often useful when when + * you need other WorkspacePersistenceProvider data deserialized + * before yours. *

    - * + * * @author Mathieu Bastian * @see Workspace */ public interface WorkspacePersistenceProvider { /** - *

    This is automatically called when saving a project file.

    - *

    Your implementation must enclose all your data xml in a tag with the name provided in your getIdentifier method.

    - * @param writer XMLStreamWriter for xml serialization of this persistence provider data + * This is automatically called when saving a project file. + *

    + * Your implementation must enclose all your data xml in a tag with the name + * provided in your getIdentifier 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); /** - *

    This is automatically called when a start element with the tag name provided in your getIdentifier method.

    - *

    Your implementation must detect the tag end element to stop reading.

    - * @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 getIdentifier method. + *

    + * 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 WorkspacePersistenceProvider + * Unique XML tag identifier for your + * WorkspacePersistenceProvider. + * * @return Unique identifier describing your data */ public String getIdentifier(); diff --git a/modules/ProjectAPI/src/main/java/org/gephi/workspace/impl/WorkspaceInformationImpl.java b/modules/ProjectAPI/src/main/java/org/gephi/workspace/impl/WorkspaceInformationImpl.java index e6d367ef781a379c8ba25dca01665e0869db1b76..97e0f8b93b36b16fce7ceb0f464b9a72498f5b39 100644 --- a/modules/ProjectAPI/src/main/java/org/gephi/workspace/impl/WorkspaceInformationImpl.java +++ b/modules/ProjectAPI/src/main/java/org/gephi/workspace/impl/WorkspaceInformationImpl.java @@ -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 listeners = new ArrayList(); + private final transient List listeners = new ArrayList(); 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); + } } } }