There are two classes here. One renders XML transcripts in JTextPane, and the other uses XPath to navigate the transcripts. Neither is part of the build yet. I'll document them more fully later when I've got to a point where they are worth sharing.

This commit is contained in:
eg3p 2002-12-12 15:17:42 +00:00
parent 86c2374706
commit 3199ff7926
2 changed files with 198 additions and 64 deletions

View file

@ -1,76 +1,30 @@
package org.thdl.quilldriver; package org.thdl.quilldriver;
import org.jaxen.jdom.JDOMXPath;
import org.jaxen.XPath; import org.jaxen.XPath;
import org.jaxen.JaxenException;
import org.jaxen.jdom.JDOMXPath;
import java.util.List;
public class TranscriptNavigator { public class TranscriptNavigator {
private boolean autoInsertFlag = false; private TranscriptNavigator() {} //can't instantiate this class
private TranscriptMediator mediator;
TranscriptNavigator(TranscriptMediator mediator) { public static Object findSingleNode(Object jdomNode, String xpathExpression) {
this.mediator = mediator; List l = findNodeSet(jdomNode, xpathExpression);
if (l == null || l.size() == 0)
return null;
else {
return l.get(0);
} }
/*
Next = ancestor-or-self::S/following-sibling::
*/
public boolean edit(String xpathExpression) {
return false;
} }
public static List findNodeSet(Object jdomNode, String xpathExpression) {
public boolean editNextText(String elementName) {
int pos = mediator.getPane().getCaretPosition();
Object next = next(pos, elementName);
if (next == null) {
if (autoInsertFlag) {
//insert after
return false;
} else
return false;
}
return false;
}
public boolean editPrevText(String elementName) {
pos = mediator.getPane().getCaretPosition();
Object prev = prev(pos, elementName);
if (prev == null) {
if (autoInsertFlag) {
//insert after
return false;
} else
return false;
}
return false;
}
public boolean highlightNext(String elementName) {
return false;
}
public boolean highlightPrev(String elementName) {
return false;
}
public Object next(int pos, String elementName) {
Object jdomNode = mediator.getNodeAtPos(int position);
if (jdomNode == null) if (jdomNode == null)
return null; return null;
XPath path = new JDOMXPath("a/b/c"); try {
List results = path.selectNodes(jdomNode); XPath path = new JDOMXPath(xpathExpression);
return path.selectNodes(jdomNode);
} catch (JaxenException je) {
je.printStackTrace();
return null; return null;
} }
public Object prev(int pos, String elementName) {
Object jdomNode = mediator.getNodeAtPos(int position);
if (jdomNode == null)
return null;
XPath path = new JDOMXPath("a/b/c");
List results = path.selectNodes(jdomNode);
return null;
} }
} }

View file

@ -0,0 +1,180 @@
package org.thdl.quilldriver;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Attribute;
import org.jdom.Text;
import java.awt.Color;
import java.util.List;
import java.util.Set;
import java.util.Iterator;
import java.util.Map;
import java.util.HashMap;
import javax.swing.JTextPane;
import javax.swing.text.Position;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.BadLocationException;
public class TranscriptRenderer {
private Document xml;
private JTextPane pane;
private StyledDocument doc;
private Map startOffsets, endOffsets;
private final float indentIncrement = 15.0F;
private final Color tagColor = Color.magenta;
private final Color attColor = Color.pink;
private final Color textColor = Color.gray;
public TranscriptRenderer(Document xmlDoc, JTextPane textPane) {
xml = xmlDoc;
pane = textPane;
render();
}
public void render() {
doc = pane.getStyledDocument();
int len = doc.getLength();
if (len > 0) {
try {
doc.remove(0, len);
} catch (BadLocationException ble) {
ble.printStackTrace();
}
}
startOffsets = new HashMap();
endOffsets = new HashMap();
Element root = xml.getRootElement();
renderElement(root, 0.0F);
//replace Integer values in startOffsets and endOffsets with Positions
Set startKeys = startOffsets.keySet();
Iterator iter = startKeys.iterator();
while (iter.hasNext()) {
Object key = iter.next();
Integer val = (Integer)startOffsets.get(key);
try {
startOffsets.put(key, doc.createPosition(val.intValue()));
} catch (BadLocationException ble) {
ble.printStackTrace();
}
}
Set endKeys = endOffsets.keySet();
iter = endKeys.iterator();
while (iter.hasNext()) {
Object key = iter.next();
Integer val = (Integer)endOffsets.get(key);
try {
endOffsets.put(key, doc.createPosition(val.intValue()));
} catch (BadLocationException ble) {
ble.printStackTrace();
}
}
}
private void renderElement(Element e, float indent) {
SimpleAttributeSet eAttributes = new SimpleAttributeSet();
StyleConstants.setLeftIndent(eAttributes, indent);
SimpleAttributeSet eColor = new SimpleAttributeSet();
StyleConstants.setForeground(eColor, tagColor);
eColor.addAttribute("xmlnode", e);
try {
int start = doc.getLength();
startOffsets.put(e, new Integer(start));
doc.insertString(doc.getLength(), e.getQualifiedName(), eColor); //insert element begin tag
List attributes = e.getAttributes();
Iterator iter = attributes.iterator();
while (iter.hasNext()) {
Attribute att = (Attribute)iter.next();
renderAttribute(att);
}
doc.insertString(doc.getLength(), " {", eColor);
doc.setParagraphAttributes(start, doc.getLength(), eAttributes, false);
doc.insertString(doc.getLength(), "\n", null);
List list = e.getContent();
iter = list.iterator();
while (iter.hasNext()) {
Object next = iter.next();
if (next instanceof Element)
renderElement((Element)next, indent + indentIncrement);
else if (next instanceof Text) {
Text t = (Text)next;
if (t.getTextTrim().length() > 0)
renderText(t, indent + indentIncrement);
}
// Also: Comment ProcessingInstruction CDATA EntityRef
}
start = doc.getLength();
doc.insertString(start, "}", eColor); //insert element end tag
doc.setParagraphAttributes(start, doc.getLength(), eAttributes, false);
endOffsets.put(e, new Integer(doc.getLength()));
doc.insertString(doc.getLength(), "\n", null);
} catch (BadLocationException ble) {
ble.printStackTrace();
}
}
private void renderAttribute(Attribute att) {
SimpleAttributeSet aColor = new SimpleAttributeSet();
StyleConstants.setForeground(aColor, attColor);
SimpleAttributeSet tColor = new SimpleAttributeSet();
StyleConstants.setForeground(tColor, textColor);
tColor.addAttribute("xmlnode", att);
String name = att.getQualifiedName();
String value = att.getValue();
try {
doc.insertString(doc.getLength(), " "+att.getQualifiedName()+"=", aColor);
startOffsets.put(att, new Integer(doc.getLength()));
doc.insertString(doc.getLength(), "\"" +att.getValue()+"\"", tColor);
endOffsets.put(att, new Integer(doc.getLength()));
} catch (BadLocationException ble) {
ble.printStackTrace();
}
}
private void renderText(Text t, float indent) {
SimpleAttributeSet tAttributes = new SimpleAttributeSet();
StyleConstants.setLeftIndent(tAttributes, indent);
StyleConstants.setForeground(tAttributes, textColor);
tAttributes.addAttribute("xmlnode", t);
try {
String s = t.getTextTrim();
int start = doc.getLength()-1;
startOffsets.put(t, new Integer(start));
doc.insertString(doc.getLength(), s, null); //insert text
int end = doc.getLength();
endOffsets.put(t, new Integer(end));
doc.setParagraphAttributes(start+1, end-start, tAttributes, false);
doc.insertString(doc.getLength(), "\n", null);
} catch (BadLocationException ble) {
ble.printStackTrace();
}
}
public Object getNodeForOffset(int offset) {
AttributeSet attSet = doc.getCharacterElement(offset).getAttributes();
return attSet.getAttribute("xmlnode");
}
public int getStartOffsetForNode(Object node) {
Position pos = (Position)startOffsets.get(node);
if (pos == null) return -1;
else return pos.getOffset();
}
public int getEndOffsetForNode(Object node) {
Position pos = (Position)endOffsets.get(node);
if (pos == null) return -1;
else return pos.getOffset();
}
public boolean isEditable(Object node) {
if (node == null) return false;
else if (node instanceof Element) return false;
else if (node instanceof Text) return true;
else if (node instanceof Attribute) return true;
else return false;
}
}