multivalent
Class Span
public
class
Span
extends Behavior
implements ContextListener, EventListener
A Span (aka Range aka Tk tag), such as a hyperlink or executable copy editor mark,
is a linear range of content that can control appearance and receives events.
It efficiently covers any amount of tree, not restricted by structural node hierarchy.
Spans are robust to insertions and deletions, during runtime and across save/restore editing of base document.
Span is not an abstract class, and in fact should be heavily used itself.
It can be used to store metadata, via attributes.
It can be created with a semantic name and its properties set in the style sheet.
If a style sheet is independent of a style sheet (as with a user annotation), one should use a "general span".
If different behavior is needed, as opposed to appearance, then subclasses are appropriate.
- moving: open, close / closeAll,
Span /
Span
/ Mark
,
Span / Span
/ Mark
- relationship to tree: getStart, getEnd, isSet,
Span /
Mark
- editing-related: stretch,
- display and events: getPriority, Span,
repaint /
long
, markDirty,
- events: getPriority, event
Version: $Revision: 1.14 $ $Date: 2003/06/02 05:10:38 $
See Also: Mark
Field Summary |
static String | GI_END |
static String | GI_START |
static String | MSG_DELETE
For use in interactive editing, deletes span, moving selection to old extent.
|
static String | MSG_EDIT
Request for interactive editing of span attributes.
|
static String | MSG_MORPH
For use in interactive editing, moves Span to extent of selection.
|
static String | MSG_UNATTACHED
Announce span that could not be reattached with confidence.
|
Map<String,Object> | pend |
Map<String,Object> | pstart |
Method Summary |
boolean | appearance(Context cx, boolean all) |
void | buildAfter(Document doc)
Attach to document tree based on saved anchor description.
|
boolean | checkRep() |
boolean | close(Node end)
Close span at end of passed Node, and attach Span to tree.
|
static int | closeAll(Node subtree)
Close all spans in subtree.
|
boolean | contains(Node n, int off) Is (Node, offset) contained within span? |
boolean | contains(Mark m) |
void | destroy()
Removes span from document and its layer.
|
void | event(AWTEvent e)
Receives synthesized java.awt.event.MouseEvent#MOUSE_ENTERED, java.awt.event.MouseEvent#MOUSE_EXITED, java.awt.event.MouseEvent#MOUSE_PRESSED, ....
|
Mark | getEnd() (Node, offset) of end of span. |
int | getPriority() |
Mark | getStart() (Node, offset) of start of span. |
boolean | isSet() Is Span attached to tree? |
void | markDirty() |
void | move(Leaf ln, int lo, Leaf rn, int ro)
Save move, for interactive use: selection, annotations.
|
void | move(Span s) Span endpoints assumed valid; just moveq + reformatting and repainting. |
void | move(Mark l, Mark r) |
void | moveq(Leaf ln, int lo, Leaf rn, int ro)
"move quick" just updates summaries, so more efficient than move(), if caller:
- guarantees that first node comes before second node (so the system doesn't have to spend time checking this), and
- handles all reformatting and repainting (including marking tree nodes dirty)
Useful using during initial tree builds, when adding spans and formatting in batch(es).
|
void | moveq(Mark start, Mark end) |
void | moveq(Span span) Useful to morph to the selection. |
void | moveqSwap(Leaf ln, int lo, Leaf rn, int ro)
Like moveq(), swapping endpoints if necessary, so that left comes before right in tree order. |
void | open(Node start)
During document creation, open span at first leaf to be created after passed node.
|
void | repaint(long ms) Repaints smallest subtree containing both endpoints. |
void | repaint() |
void | restore(ESISNode n, Map<String,Object> attr, Layer layer)
Given ESIS subtree, pluck class-specific information from attributes, call super.restore() for locations.
|
ESISNode | save()
Stuff instance state into attributes; if save buffer not null, write out corresponding XML.
|
boolean | semanticEventAfter(SemanticEvent se, String msg) Recognize "deleteSpan " and "morphSpan ". |
boolean | semanticEventBefore(SemanticEvent se, String msg) Morphing and deletion menu items in popup. |
static void | stretch(Leaf l, INode within)
Removing leaf from tree, but preserve its span transitions
by stretching end transitions to previous node and start transitions to next node.
|
String | toString()
Subclasses should extend to check any attributes they add. |
public static final String GI_END
public static final String GI_START
public static final String MSG_DELETE
For use in interactive editing, deletes span, moving selection to old extent.
"deleteSpan".
public static final String MSG_EDIT
Request for interactive editing of span attributes.
"editSpan".
public static final String MSG_MORPH
For use in interactive editing, moves Span to extent of selection.
"morphSpan".
public static final String MSG_UNATTACHED
Announce span that could not be reattached with confidence.
"unattachedSpan": arg= Span instance.
public Map<String,Object> pend
public Map<String,Object> pstart
public boolean appearance(
Context cx, boolean all)
Attach to document tree based on saved anchor description.
Not used/needed during creation of fresh spans as during interactive annotation.
public boolean checkRep()
public boolean close(
Node end)
Close span at end of passed Node, and attach Span to tree.
Since this is used during tree construction, no nodes are marked dirty as that would be redundant.
If the span cannot be attached, the caller probably wants to
destroy it;
however, the HTML media adaptor takes the case of HTML 0-length
>a name=...<
spans
and instead attaches and 'id' attribute to the previous node.
Returns: true if attached span, false if couldn't attach or 0-length
public static int closeAll(
Node subtree)
Close all spans in
subtree.
Useful in a couple ways:
for a media adaptor to conveniently and concisely close all pending spans at the end of a document, and
to guarantee that all spans are closed even if an explicit end to the span is missing in the concrete document.
Returns: count of spans successfully attached to tree
public boolean contains(
Node n, int off)
Is (Node, offset) contained within span?
public boolean contains(
Mark m)
public void destroy()
Removes span from document and its layer.
Different from moveq(null), which removes from document tree but not from layer.
If caller will handle all reformatting and repainting, as during a batch destory(), first moveq(null) on span.
public void event(AWTEvent e)
Receives synthesized java.awt.event.MouseEvent#MOUSE_ENTERED, java.awt.event.MouseEvent#MOUSE_EXITED, java.awt.event.MouseEvent#MOUSE_PRESSED, ....
For the purposes of event passing, functions more as tree node than behavior (with before/after).
public final
Mark getEnd()
(Node, offset) of end of span.
public int getPriority()
public final
Mark getStart()
(Node, offset) of start of span.
public boolean isSet()
Is Span attached to tree?
public void markDirty()
public void move(
Leaf ln, int lo,
Leaf rn, int ro)
Save move, for interactive use: selection, annotations.
Sets start point < end point, handles necessary reformatting and repainting.
Reformats both old range and new range, as with style sheets and hardcode in subclasses, can't tell when that's not necessary.
(Or, moveq() + swapping endpoints if necessary + reformatting/repainting.)
Span endpoints assumed valid; just moveq + reformatting and repainting.
public void moveq(
Leaf ln, int lo,
Leaf rn, int ro)
"move quick" just updates summaries, so more efficient than move(), if caller:
- guarantees that first node comes before second node (so the system doesn't have to spend time checking this), and
- handles all reformatting and repainting (including marking tree nodes dirty)
Useful using during initial tree builds, when adding spans and formatting in batch(es).
Checks that endpoint offsets are valid, that is, >=0 and
public void moveq(
Span span)
Useful to morph to the selection.
public void moveqSwap(
Leaf ln, int lo,
Leaf rn, int ro)
Like moveq(), swapping endpoints if necessary, so that left comes before right in tree order.
public void open(
Node start)
During document creation, open span at first leaf to be created after passed node.
Typically, document formats begin spans before the content to which they apply has been seen,
which means bookkeeping for the span name, type, start point, attributes and so on for when then end of span is seen,
and adjusting the start point to the first leaf created after last node known at
open.
Instead, media adaptors can create the span and configure it and set the start point with
open with
the last node created, which can be an internal node, and
close adjusts the start point.
If both start and end points already exist, use
Span.
All spans open
ed must be close
ed or there will be memory leaks.
See Also: and
for examples of use
public void repaint(long ms)
Repaints smallest subtree containing both endpoints.
public void repaint()
public void restore(
ESISNode n, Map<String,Object> attr,
Layer layer)
Given ESIS subtree, pluck class-specific information from attributes, call super.restore() for locations.
Attributes named
start
and
end
are reserved to hold Robust Location data.
See Also: RobustLocation
Stuff instance state into attributes; if save buffer not null, write out corresponding XML.
Subclass should override if have interesting content (can stuff content into attr then super.save()).
If span is not attached to tree at save time, its old attachment points are retained.
This way, spans that can't be attached presently can be tried again without degradation.
Recognize "deleteSpan " and "morphSpan ".
Morphing and deletion menu items in popup.
public static void stretch(
Leaf l,
INode within)
Removing leaf from tree, but preserve its span transitions
by stretching end transitions to previous node and start transitions to next node.
If there is no previous node for and end transition, or next node for a start, the span is removed.
public String toString()
Subclasses should extend to check any attributes they add.
Parameters: endpoints if false, don't consider endpoints.
public boolean equals(Object o, boolean endpoints) {
return this == o; ?
if (this == o) return true;
if (o==null || !(o instanceof Span)) return false;
Span span2 = (Span)o;
boolean eq = true;
if (eq && endpoints) {
eq = (!isSet() && !span2.isSet()) || (getStart().equals(span2.getStart()) && getEnd().equals(span2.getEnd()));
// check pstart and pend too?
}
if (eq) eq = getName().equals(span2.getName());
// attributes ...
return eq;
}