181 lines
5.7 KiB
Java
181 lines
5.7 KiB
Java
|
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;
|
||
|
}
|
||
|
}
|