public abstract class AbstractSavable extends Object implements Savable
Savable
interface and
additional contracts, including dealing with Savable.REGISTRY
.
The human presentable name of the object to be saved is provided by
implementing AbstractSavable.findDisplayName()
. In case this object wants
to be visually represented with an icon, it can also implement Icon
interface (and delegate to ImageUtilities.loadImageIcon(java.lang.String, boolean)
result). Here is example of typical implementation:
class MySavable extends AbstractSavable { private final Object obj; public MySavable(Object obj) { this.obj = obj; register(); } protected String findDisplayName() { return "My name is " + obj.toString(); // get display name somehow } protected void handleSave() throws IOException { // save 'obj' somehow } public boolean equals(Object other) { if (other instanceof MySavable) { return ((MySavable)other).obj.equals(obj); } return false; } public int hashCode() { return obj.hashCode(); } }
Modifier | Constructor and Description |
---|---|
protected |
AbstractSavable()
Constructor for subclasses.
|
Modifier and Type | Method and Description |
---|---|
abstract boolean |
equals(Object obj)
Equals and
AbstractSavable.hashCode() need to be properly implemented
by subclasses to correctly implement equality contract. |
protected abstract String |
findDisplayName()
Finds suitable display name for the object this
Savable
represents. |
protected abstract void |
handleSave()
To be overriden by subclasses to handle the actual save of
the object.
|
abstract int |
hashCode()
HashCode and
AbstractSavable.equals(java.lang.Object) need to be properly implemented
by subclasses, so two Savable s representing the same object
beneath are really equal and have the same AbstractSavable.hashCode() . |
protected void |
register()
Tells the system to register this
Savable into Savable.REGISTRY . |
void |
save()
Implementation of
Savable.save() contract. |
String |
toString()
Human descriptive, localized name of the savable.
|
protected void |
unregister()
Removes this
Savable from the Savable.REGISTRY (if it
is present there, by relying on AbstractSavable.equals(java.lang.Object)
and AbstractSavable.hashCode() ). |
public final void save() throws IOException
Savable.save()
contract. Calls
AbstractSavable.handleSave()
and AbstractSavable.unregister()
.save
in interface Savable
IOException
- if call to AbstractSavable.handleSave()
throws IOExceptionprotected abstract String findDisplayName()
Savable
represents.protected abstract void handleSave() throws IOException
IOException
public abstract boolean equals(Object obj)
AbstractSavable.hashCode()
need to be properly implemented
by subclasses to correctly implement equality contract.
Two Savable
s should be equal
if they represent the same underlying object beneath them. Without
correct implementation proper behavior of AbstractSavable.register()
and
AbstractSavable.unregister()
cannot be guaranteed.public abstract int hashCode()
AbstractSavable.equals(java.lang.Object)
need to be properly implemented
by subclasses, so two Savable
s representing the same object
beneath are really equal and have the same AbstractSavable.hashCode()
.hashCode
in class Object
AbstractSavable.equals(java.lang.Object)
protected final void register()
Savable
into Savable.REGISTRY
.
Only one Savable
(according to AbstractSavable.equals(java.lang.Object)
and
AbstractSavable.hashCode()
) can be in the registry. New call to AbstractSavable.register()
replaces any previously registered and equal Savable
s. After this call
the Savable.REGISTRY
holds a strong reference to this
which prevents this
object to be garbage collected until it
is unregistered
or replaced by
equal one
.protected final void unregister()
Savable
from the Savable.REGISTRY
(if it
is present there, by relying on AbstractSavable.equals(java.lang.Object)
and AbstractSavable.hashCode()
).