package edu.cmu.minorthird.text.gui;
import java.util.Iterator;
import java.util.Set;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.JTextPane;
import javax.swing.text.SimpleAttributeSet;
import edu.cmu.minorthird.text.EmptyLabels;
import edu.cmu.minorthird.text.FancyLoader;
import edu.cmu.minorthird.text.MonotonicTextLabels;
import edu.cmu.minorthird.text.NestedTextLabels;
import edu.cmu.minorthird.text.Span;
import edu.cmu.minorthird.text.TextLabels;
import edu.cmu.minorthird.text.mixup.MixupInterpreter;
import edu.cmu.minorthird.text.mixup.MixupProgram;
import edu.cmu.minorthird.util.gui.ComponentViewer;
import edu.cmu.minorthird.util.gui.Controllable;
import edu.cmu.minorthird.util.gui.ControlledViewer;
import edu.cmu.minorthird.util.gui.ParallelViewer;
import edu.cmu.minorthird.util.gui.ViewerControls;
import edu.cmu.minorthird.util.gui.ViewerFrame;
/**
* View the contents of a span, using the util.gui.Viewer framework.
*
* @author William Cohen
*/
public class SpanViewer extends ParallelViewer implements Controllable{
static final long serialVersionUID=200803014L;
private static final int DEFAULT_CONTEXT=10;
private TextLabels labels;
private Span span;
private TextViewer textViewer;
public SpanViewer(TextLabels labels,Span span){
super();
this.labels=labels;
this.span=span;
this.textViewer=new TextViewer(labels,span);
addSubView("Text",textViewer);
addSubView("Tokens",new TokenViewer(labels,span));
addSubView("Ids",new IdViewer(labels,span));
setContent(span);
}
public TextLabels getLabels(){
return labels;
}
public Span getSpan(){
return span;
}
@Override
public void applyControls(ViewerControls controls){
textViewer.applyControls(controls);
}
@Override
public boolean canReceive(Object obj){
return obj instanceof Span;
}
/** A text view of a span, plus controls */
public static class ControlledTextViewer extends ControlledViewer{
static final long serialVersionUID=200803014L;
private Span span;
public ControlledTextViewer(Span span){
this.span=span;
TextControls controls=new TextControls();
MyViewer viewer=new MyViewer();
setComponents(viewer,controls);
setContent(span);
}
private class MyViewer extends ComponentViewer implements Controllable{
static final long serialVersionUID=200803014L;
public TextControls controls;
public Span span;
@Override
public JComponent componentFor(Object o){
this.span=(Span)o;
int contextWidth=
controls==null?DEFAULT_CONTEXT:controls.contextSlider.getValue();
SpanDocument doc=new SpanDocument(span,contextWidth);
JTextPane textPane=new JTextPane(doc);
return new JScrollPane(textPane);
}
@Override
public void applyControls(ViewerControls controls){
this.controls=(TextControls)controls;
setContent(span,true);
revalidate();
}
}
private class TextControls extends ViewerControls{
static final long serialVersionUID=200803014L;
public JSlider contextSlider;
@Override
public void initialize(){
contextSlider=new JSlider(0,100,DEFAULT_CONTEXT);
add(new JLabel("Context:"));
add(contextSlider);
addApplyButton();
}
}
public Span getSpan(){
return span;
}
}
/** A text view of a span. */
public static class TextViewer extends ComponentViewer implements
Controllable{
static final long serialVersionUID=200803014L;
private TextLabels labels;
private Span span;
private SpanDocument doc;
private JTextPane textPane;
private int context=DEFAULT_CONTEXT;
public TextViewer(Span span){
this(new EmptyLabels(),span,DEFAULT_CONTEXT);
}
public TextViewer(Span span,int context){
this(new EmptyLabels(),span,context);
}
public TextViewer(TextLabels labels,Span span){
this(labels,span,DEFAULT_CONTEXT);
}
public TextViewer(TextLabels labels,Span span,int context){
super();
this.labels=labels;
this.span=span;
this.context=context;
}
public void highlight(Span span,SimpleAttributeSet color){
if(color!=null)
doc.highlight(span,color);
}
@Override
public JComponent componentFor(Object o){
span=(Span)o;
doc=new SpanDocument(span,context);
textPane=new JTextPane(doc);
textPane.setEditable(false);
return new JScrollPane(textPane);
}
@Override
public void applyControls(ViewerControls viewerControls){
MarkupControls controls=(MarkupControls)viewerControls;
doc.resetHighlights();
for(Iterator<String> i=labels.getTypes().iterator();i.hasNext();){
String type=i.next();
SimpleAttributeSet color=controls.getColor(type);
if(color!=null){
for(Iterator<Span> j=
labels.instanceIterator(type,span.getDocumentId());j.hasNext();){
Span typeSpan=j.next();
doc.highlight(typeSpan,color);
}
}
}
for(Iterator<String> i=controls.getColoredProperties().iterator();i.hasNext();){
String prop=i.next();
for(Iterator<Span> j=
labels.getSpansWithProperty(prop,span.getDocumentId());j.hasNext();){
Span span=j.next();
String val=labels.getProperty(span,prop);
SimpleAttributeSet color=controls.getColor(prop,val);
if(color!=null)
doc.highlight(span,color);
}
}
}
}
// note: this is rather expensive to build
/** A tokenized view of a span. */
public static class TokenViewer extends ComponentViewer{
static final long serialVersionUID=200803014L;
private TextLabels labels;
private Span span;
public TokenViewer(TextLabels labels,Span span){
super();
this.labels=labels;
this.span=span;
}
public Span getSpan(){
return span;
}
@Override
public JComponent componentFor(Object o){
// bug in here somewhere...
Span s=(Span)o;
Set<String> propSet=labels.getTokenProperties();
String[] props=propSet.toArray(new String[propSet.size()]);
Object[][] table=new Object[s.size()][props.length+1];
for(int i=0;i<s.size();i++){
table[i][0]=s.getToken(i).getValue(); // bug here
for(int j=0;j<props.length;j++){
table[i][j+1]=labels.getProperty(s.getToken(i),props[j]);
if(table[i][j+1]==null)
table[i][j+1]="-";
}
}
String[] colNames=new String[props.length+1];
colNames[0]="token";
for(int j=0;j<props.length;j++)
colNames[j+1]=props[j];
return new JScrollPane(new JTable(table,colNames));
}
}
/** View of the span's documentId and documentGroupId */
public static class IdViewer extends ComponentViewer{
static final long serialVersionUID=200803014L;
private TextLabels labels;
private Span span;
public IdViewer(TextLabels labels,Span span){
super();
this.labels=labels;
this.span=span;
}
public TextLabels getLabels(){
return labels;
}
public Span getSpan(){
return span;
}
@Override
public JComponent componentFor(Object o){
Span s=(Span)o;
Object[][] table=new Object[1][2];
table[0][0]=s.getDocumentId();
table[0][1]=s.getDocumentGroupId();
String[] colNames=new String[]{"documentId","documentGroupId"};
return new JScrollPane(new JTable(table,colNames));
}
}
// fancy test case
public static void main(String[] argv){
try{
TextLabels labels0=
FancyLoader.loadTextLabels("demos/sampleData/seminar-subset");
final MonotonicTextLabels labels=new NestedTextLabels(labels0);
MixupProgram p=
new MixupProgram(new String[]{
"defTokenProp entity:time =top: ... [@stime] ...",
"defTokenProp entity:speaker =top: ... [@speaker] ...",
"defTokenProp entity:loc =top: ... [@location] ...",
"defTokenProp freeText:true =top: ... [@sentence] ...",});
MixupInterpreter interp=new MixupInterpreter(p);
interp.eval(labels);
Span s=labels.getTextBase().documentSpanIterator().next();
SpanViewer sv=new SpanViewer(labels,s);
MarkupControls mp=new MarkupControls(labels);
ControlledViewer v=new ControlledViewer(sv,mp);
v.setContent(s);
// Span subspan = s.subSpan(10,5);
// Viewer u = new ControlledTextViewer(subspan);
new ViewerFrame("SpanViewer",v);
}catch(Exception e){
e.printStackTrace();
}
}
}