You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2015/05/13 15:15:22 UTC
svn commit: r1679203 -
/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/CasAnnotationViewer.java
Author: schor
Date: Wed May 13 13:15:21 2015
New Revision: 1679203
URL: http://svn.apache.org/r1679203
Log:
[UIMA-3347] applied patch 2015-5-8
Modified:
uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/CasAnnotationViewer.java
Modified: uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/CasAnnotationViewer.java
URL: http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/CasAnnotationViewer.java?rev=1679203&r1=1679202&r2=1679203&view=diff
==============================================================================
--- uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/CasAnnotationViewer.java (original)
+++ uima/uimaj/trunk/uimaj-tools/src/main/java/org/apache/uima/tools/viewer/CasAnnotationViewer.java Wed May 13 13:15:21 2015
@@ -39,9 +39,7 @@ import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.Hashtable;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -86,6 +84,7 @@ import org.apache.uima.cas.Feature;
import org.apache.uima.cas.FeatureStructure;
import org.apache.uima.cas.SofaFS;
import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
import org.apache.uima.cas.impl.BooleanArrayFSImpl;
import org.apache.uima.cas.impl.ByteArrayFSImpl;
import org.apache.uima.cas.impl.DoubleArrayFSImpl;
@@ -95,6 +94,7 @@ import org.apache.uima.cas.impl.LongArra
import org.apache.uima.cas.impl.ShortArrayFSImpl;
import org.apache.uima.cas.impl.StringArrayFSImpl;
import org.apache.uima.cas.text.AnnotationFS;
+import org.apache.uima.cas.text.AnnotationIndex;
import org.apache.uima.jcas.JCas;
import org.apache.uima.jcas.tcas.Annotation;
import org.apache.uima.tools.viewer.EntityResolver.Entity;
@@ -174,21 +174,22 @@ public class CasAnnotationViewer extends
Color.getHSBColor(250f / 360, 0.75f, BRIGHT) };
private CAS cas;
+ private TypeSystem typeSystem;
private Type stringType;
private Type fsArrayType;
private boolean useConsistentColors = true;
- private List<String> highFrequencyTypes = new ArrayList<String>();
- private String[] boldFaceKeyWords = new String[0];
- private int[] boldFaceSpans = new int[0];
- private Set<String> hiddenFeatureNames = new HashSet<String>();
- private Set<String> hiddenTypeNames = new HashSet<String>();
- private Set<String> displayedTypeNames = null;
- private Set<String> initiallySelectedTypeNames = null;
- private boolean hideUnselectedCheckboxes = false;
- private List<String> userTypes = null;
- private Set<String> typesNotChecked = new HashSet<String>();
- private Map<String, Color> typeColorMap = new HashMap<String, Color>();
- private EntityResolver mEntityResolver = new DefaultEntityResolver();
+ private List<String> highFrequencyTypes;
+ private String[] boldFaceKeyWords;
+ private int[] boldFaceSpans;
+ private Set<String> hiddenFeatureNames;
+ private Set<String> hiddenTypeNames;
+ private Set<String> displayedTypeNames;
+ private Set<String> initiallySelectedTypeNames;
+ private boolean hideUnselectedCheckBoxes;
+ private List<String> userTypes;
+ private Set<String> typesNotChecked;
+ private Map<String, Color> typeColorMap;
+ private EntityResolver entityResolver = new DefaultEntityResolver();
private boolean entityViewEnabled = false;
private short viewMode = MODE_ANNOTATIONS;
@@ -218,6 +219,7 @@ public class CasAnnotationViewer extends
* Creates a CAS Annotation Viewer.
*/
public CasAnnotationViewer() {
+ this.viewMode = MODE_ANNOTATIONS;
this.setLayout(new BorderLayout());
// create a horizonal JSplitPane
this.createHorizontalSplitPane();
@@ -229,23 +231,36 @@ public class CasAnnotationViewer extends
this.add(this.createControlPanel(), BorderLayout.SOUTH);
// initialize hidden feature names map
- this.hiddenFeatureNames.addAll(Arrays.asList(DEFAULT_HIDDEN_FEATURES));
+ this.hiddenFeatureNames = new HashSet<String>(Arrays.asList(DEFAULT_HIDDEN_FEATURES));
}
private JPanel createControlPanel() {
- JPanel buttonPanel = new JPanel();
+ JPanel controlPanel = new JPanel();
+ controlPanel.setLayout(new BorderLayout());
+ controlPanel.add(this.createViewPanel(), BorderLayout.CENTER);
+ controlPanel.add(this.createSelectButtonPanel(), BorderLayout.SOUTH);
+ return controlPanel;
+ }
+
+ private JPanel createSelectButtonPanel() {
+ JPanel selectButtonPanel = new JPanel();
this.createSelectAllButton();
- buttonPanel.add(this.selectAllButton);
+ selectButtonPanel.add(this.selectAllButton);
this.createDeselectAllButton();
- buttonPanel.add(this.deselectAllButton);
- this.createShowHidenUnselectedButton();
- buttonPanel.add(this.showHideUnselectedButton);
+ selectButtonPanel.add(this.deselectAllButton);
+ this.createShowHideUnselectedButton();
+ selectButtonPanel.add(this.showHideUnselectedButton);
+ return selectButtonPanel;
+ }
+
+ private JPanel createViewPanel() {
+ JPanel viewPanel = new JPanel();
+ viewPanel.setLayout(new BorderLayout());
this.createSofaSelectionPanel();
- buttonPanel.add(this.sofaSelectionPanel);
+ viewPanel.add(this.sofaSelectionPanel, BorderLayout.NORTH);
this.createViewModePanel();
- buttonPanel.add(this.viewModePanel);
-
- return buttonPanel;
+ viewPanel.add(this.viewModePanel, BorderLayout.CENTER);
+ return viewPanel;
}
private void createViewModePanel() {
@@ -262,32 +277,42 @@ public class CasAnnotationViewer extends
}
private void createEntityModeButton() {
- this.entityModeButton = new JRadioButton("Entities");
+ this.entityModeButton = new JRadioButton("Entities", this.viewMode == MODE_ENTITIES);
this.entityModeButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- viewMode = MODE_ENTITIES;
- display();
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JRadioButton radioButton = (JRadioButton) e.getSource();
+ if (!radioButton.isSelected() || viewMode == MODE_ENTITIES) {
+ // If the radio button is unselected, there is no need to refresh the UI.
+ // If the view mode is already entities view mode, there is no need to refresh the UI.
+ return;
}
+ viewMode = MODE_ENTITIES;
+ display();
+ }
});
}
private void createAnnotationModeButton() {
- this.annotationModeButton = new JRadioButton("Annotations");
- this.annotationModeButton.setSelected(true);
+ this.annotationModeButton = new JRadioButton("Annotations", this.viewMode == MODE_ANNOTATIONS);
this.annotationModeButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- viewMode = MODE_ANNOTATIONS;
- display();
- }
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ JRadioButton radioButton = (JRadioButton) e.getSource();
+ if (!radioButton.isSelected() || viewMode == MODE_ANNOTATIONS) {
+ // If the radio button is unselected, there is no need to refresh the UI.
+ // If the view mode is already annotations view mode, there is no need to refresh the UI.
+ return;
+ }
+ viewMode = MODE_ANNOTATIONS;
+ display();
+ }
});
}
private void createSofaSelectionPanel() {
this.sofaSelectionPanel = new JPanel();
- JLabel sofaSelectionLabel = new JLabel("Sofa:");
- this.sofaSelectionPanel.add(sofaSelectionLabel);
+ this.sofaSelectionPanel.add(new JLabel("Sofa:"));
this.createSofaSelectionComboBox();
this.sofaSelectionPanel.add(this.sofaSelectionComboBox);
}
@@ -296,68 +321,68 @@ public class CasAnnotationViewer extends
private void createSofaSelectionComboBox() {
this.sofaSelectionComboBox = new JComboBox();
this.sofaSelectionComboBox.addItemListener(new ItemListener() {
- @Override
- public void itemStateChanged(ItemEvent e) {
- if (e.getSource() == sofaSelectionComboBox) {
- // a new sofa was selected. Switch to that view and update display
- String sofaId = (String) e.getItem();
- if ("DEFAULT".equals(sofaId)) {
- cas = cas.getView(CAS.NAME_DEFAULT_SOFA);
- } else {
- cas = cas.getView(sofaId);
- }
- display();
- }
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getSource() != sofaSelectionComboBox || cas == null) {
+ return;
+ }
+ // a new sofa was selected. Switch to that view and update display
+ String sofaId = (String) e.getItem();
+ CAS newCas = "DEFAULT".equalsIgnoreCase(sofaId) ? cas.getView(CAS.NAME_DEFAULT_SOFA) : cas.getView(sofaId);
+ if (newCas != cas) {
+ cas = newCas;
+ display();
}
+ }
});
}
- private void createShowHidenUnselectedButton() {
+ private void createShowHideUnselectedButton() {
this.showHideUnselectedButton = new JButton("Hide Unselected");
this.showHideUnselectedButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- hideUnselectedCheckboxes = !hideUnselectedCheckboxes;
- display();
- }
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ hideUnselectedCheckBoxes = !hideUnselectedCheckBoxes;
+ display();
+ }
});
}
private void createDeselectAllButton() {
this.deselectAllButton = new JButton("Deselect All");
this.deselectAllButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- Iterator<JCheckBox> cbIter = (viewMode == MODE_ANNOTATIONS) ? typeToCheckBoxMap.values().iterator()
- : entityToCheckBoxMap.values().iterator();
- while (cbIter.hasNext()) {
- cbIter.next().setSelected(false);
- }
- display();
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Iterator<JCheckBox> cbIter = (viewMode == MODE_ANNOTATIONS) ? typeToCheckBoxMap.values().iterator()
+ : entityToCheckBoxMap.values().iterator();
+ while (cbIter.hasNext()) {
+ cbIter.next().setSelected(false);
}
+ display();
+ }
});
}
private void createSelectAllButton() {
this.selectAllButton = new JButton("Select All");
this.selectAllButton.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- Iterator<JCheckBox> cbIter = (viewMode == MODE_ANNOTATIONS) ? typeToCheckBoxMap.values().iterator()
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ Iterator<JCheckBox> cbIter = (viewMode == MODE_ANNOTATIONS) ? typeToCheckBoxMap.values().iterator()
: entityToCheckBoxMap.values().iterator();
- while (cbIter.hasNext()) {
- cbIter.next().setSelected(true);
- }
- display();
+ while (cbIter.hasNext()) {
+ cbIter.next().setSelected(true);
}
+ display();
+ }
});
}
private void createHorizontalSplitPane() {
this.horizontalSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
- this.horizontalSplitPane.setResizeWeight(0.6);
+ this.horizontalSplitPane.setResizeWeight(0.6);
// create a vertical JSplitPane and add to left of horizSplitPane
- this.createVerticalSplitPane();
+ this.createVerticalSplitPane();
this.horizontalSplitPane.setLeftComponent(this.verticalSplitPane);
// right pane has a JTree
this.horizontalSplitPane.setRightComponent(this.createTreePanel());
@@ -369,12 +394,12 @@ public class CasAnnotationViewer extends
treePanel.add(new JLabel("Click In Text to See Annotation Detail"), BorderLayout.NORTH);
this.createSelectedAnnotationTree();
treePanel.add(new JScrollPane(this.selectedAnnotationTree), BorderLayout.CENTER);
- return treePanel;
+ return treePanel;
}
private void createSelectedAnnotationTree() {
this.selectedAnnotationTreeModel = new DefaultTreeModel(new DefaultMutableTreeNode("Annotations"));
- this.selectedAnnotationTree = new JTree(selectedAnnotationTreeModel) {
+ this.selectedAnnotationTree = new JTree(this.selectedAnnotationTreeModel) {
private static final long serialVersionUID = -7882967150283952907L;
public Dimension getPreferredScrollableViewportSize() {
@@ -386,53 +411,51 @@ public class CasAnnotationViewer extends
this.selectedAnnotationTree.setRootVisible(true);
this.selectedAnnotationTree.setCellRenderer(new AnnotationTreeCellRenderer());
this.selectedAnnotationTree.addTreeWillExpandListener(new TreeWillExpandListener() {
- @Override
- public void treeWillExpand(TreeExpansionEvent event)
- throws ExpandVetoException {
- // if FS node is expanded and it has a dummy child, replace with
- // feature value nodes (this is what lets us do infinite tree)
- Object lastPathComponent = event.getPath().getLastPathComponent();
- if (lastPathComponent instanceof DefaultMutableTreeNode) {
- DefaultMutableTreeNode expandedNode = (DefaultMutableTreeNode) lastPathComponent;
- Object userObj = expandedNode.getUserObject();
- if (userObj instanceof FsTreeNodeObject) {
- TreeNode firstChild = expandedNode.getFirstChild();
- if (firstChild instanceof DefaultMutableTreeNode
- && ((DefaultMutableTreeNode) firstChild).getUserObject() == null) {
- expandedNode.removeAllChildren();
- FeatureStructure fs = ((FsTreeNodeObject) userObj).getFeatureStructure();
- addFeatureTreeNodes(expandedNode, fs);
- ((JTree) event.getSource()).treeDidChange();
- }
+ @Override
+ public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
+ // if FS node is expanded and it has a dummy child, replace with
+ // feature value nodes (this is what lets us do infinite tree)
+ Object lastPathComponent = event.getPath().getLastPathComponent();
+ if (lastPathComponent instanceof DefaultMutableTreeNode) {
+ DefaultMutableTreeNode expandedNode = (DefaultMutableTreeNode) lastPathComponent;
+ Object userObject = expandedNode.getUserObject();
+ if (userObject instanceof FsTreeNodeObject) {
+ TreeNode firstChild = expandedNode.getFirstChild();
+ if (firstChild instanceof DefaultMutableTreeNode
+ && ((DefaultMutableTreeNode) firstChild).getUserObject() == null) {
+ expandedNode.removeAllChildren();
+ FeatureStructure fs = ((FsTreeNodeObject) userObject).getFeatureStructure();
+ addFeatureTreeNodes(expandedNode, fs);
+ ((JTree) event.getSource()).treeDidChange();
}
}
- }
+ }
+ }
- @Override
- public void treeWillCollapse(TreeExpansionEvent event)
- throws ExpandVetoException {
- }
+ @Override
+ public void treeWillCollapse(TreeExpansionEvent e) throws ExpandVetoException {
+ }
});
this.selectedAnnotationTree.addTreeExpansionListener(new TreeExpansionListener() {
- @Override
- public void treeExpanded(TreeExpansionEvent event) {
- // if a Type node is expanded and has only one child,
- // also expand this child (a usability improvement)
- Object lastPathComponent = event.getPath().getLastPathComponent();
- if (lastPathComponent instanceof DefaultMutableTreeNode) {
- DefaultMutableTreeNode expandedNode = (DefaultMutableTreeNode) lastPathComponent;
- Object userObj = expandedNode.getUserObject();
- if (userObj instanceof TypeTreeNodeObject && expandedNode.getChildCount() == 1) {
- TreePath childPath = event.getPath().pathByAddingChild(expandedNode.getFirstChild());
- ((JTree) event.getSource()).expandPath(childPath);
- ((JTree) event.getSource()).treeDidChange();
- }
+ @Override
+ public void treeExpanded(TreeExpansionEvent event) {
+ // if a Type node is expanded and has only one child,
+ // also expand this child (a usability improvement)
+ Object lastPathComponent = event.getPath().getLastPathComponent();
+ if (lastPathComponent instanceof DefaultMutableTreeNode) {
+ DefaultMutableTreeNode expandedNode = (DefaultMutableTreeNode) lastPathComponent;
+ Object userObject = expandedNode.getUserObject();
+ if (userObject instanceof TypeTreeNodeObject && expandedNode.getChildCount() == 1) {
+ TreePath childPath = event.getPath().pathByAddingChild(expandedNode.getFirstChild());
+ ((JTree) event.getSource()).expandPath(childPath);
+ ((JTree) event.getSource()).treeDidChange();
}
- }
+ }
+ }
- @Override
- public void treeCollapsed(TreeExpansionEvent event) {
- }
+ @Override
+ public void treeCollapsed(TreeExpansionEvent event) {
+ }
});
}
@@ -490,29 +513,27 @@ public class CasAnnotationViewer extends
this.textPane.setMinimumSize(new Dimension(200, 100));
// add mouse listener to update annotation tree
this.textPane.addMouseListener(new MouseListener() {
- @Override
- public void mouseClicked(MouseEvent e) {
- if (viewMode == MODE_ANNOTATIONS) {
- int pos = textPane.viewToModel(e.getPoint());
- updateSelectedAnnotationTree(pos);
- }
- }
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ int pos = textPane.viewToModel(e.getPoint());
+ updateSelectedAnnotationTree(pos);
+ }
- @Override
- public void mousePressed(MouseEvent e) {
- }
-
- @Override
- public void mouseReleased(MouseEvent e) {
- }
-
- @Override
- public void mouseEntered(MouseEvent e) {
- }
-
- @Override
- public void mouseExited(MouseEvent e) {
- }
+ @Override
+ public void mousePressed(MouseEvent e) {
+ }
+
+ @Override
+ public void mouseReleased(MouseEvent e) {
+ }
+
+ @Override
+ public void mouseEntered(MouseEvent e) {
+ }
+
+ @Override
+ public void mouseExited(MouseEvent e) {
+ }
});
this.textScrollPane = new JScrollPane(this.textPane);
}
@@ -524,7 +545,7 @@ public class CasAnnotationViewer extends
public CasAnnotationViewer(boolean aEntityViewEnabled) {
this();
}
-
+
/**
* @return Returns the userTypes.
*/
@@ -550,10 +571,20 @@ public class CasAnnotationViewer extends
*/
public void setHighFrequencyTypes(String[] aTypeNames) {
// store these types for later
- highFrequencyTypes.clear();
- highFrequencyTypes.addAll(Arrays.asList(aTypeNames));
- typeColorMap.clear();
- assignColors(highFrequencyTypes);
+ if (this.highFrequencyTypes == null) {
+ this.highFrequencyTypes = new ArrayList<String>();
+ }
+ if (this.highFrequencyTypes.size() > 0) {
+ this.highFrequencyTypes.clear();
+ }
+ this.highFrequencyTypes.addAll(Arrays.asList(aTypeNames));
+ if (this.typeColorMap == null) {
+ this.typeColorMap = new HashMap<String, Color>();
+ }
+ if (this.typeColorMap.size() > 0) {
+ this.typeColorMap.clear();
+ }
+ this.assignTypeColors(this.highFrequencyTypes);
}
/**
@@ -568,10 +599,15 @@ public class CasAnnotationViewer extends
*/
public void setDisplayedTypes(String[] aDisplayedTypeNames) {
if (aDisplayedTypeNames == null) {
- displayedTypeNames = null;
+ this.displayedTypeNames = null;
} else {
- displayedTypeNames = new HashSet<String>();
- displayedTypeNames.addAll(Arrays.asList(aDisplayedTypeNames));
+ if (this.displayedTypeNames == null) {
+ this.displayedTypeNames = new HashSet<String>();
+ }
+ if (this.displayedTypeNames.size() > 0) {
+ this.displayedTypeNames.clear();
+ }
+ this.displayedTypeNames.addAll(Arrays.asList(aDisplayedTypeNames));
}
}
@@ -582,8 +618,13 @@ public class CasAnnotationViewer extends
* names of types that are never to be highlighted.
*/
public void setHiddenTypes(String[] aTypeNames) {
- hiddenTypeNames.clear();
- hiddenTypeNames.addAll(Arrays.asList(aTypeNames));
+ if (this.hiddenTypeNames == null) {
+ this.hiddenTypeNames = new HashSet<String>();
+ }
+ if (this.hiddenTypeNames.size() > 0) {
+ this.hiddenTypeNames.clear();
+ }
+ this.hiddenTypeNames.addAll(Arrays.asList(aTypeNames));
}
/**
@@ -621,11 +662,16 @@ public class CasAnnotationViewer extends
* array of (short) feature names to be hidden
*/
public void setHiddenFeatures(String[] aFeatureNames) {
- hiddenFeatureNames.clear();
+ if (this.hiddenFeatureNames == null) {
+ this.hiddenFeatureNames = new HashSet<String>();
+ }
+ if (this.hiddenFeatureNames.size() > 0) {
+ this.hiddenFeatureNames.clear();
+ }
// add default hidden features
- hiddenFeatureNames.addAll(Arrays.asList(DEFAULT_HIDDEN_FEATURES));
+ this.hiddenFeatureNames.addAll(Arrays.asList(DEFAULT_HIDDEN_FEATURES));
// add user-defined hidden features
- hiddenFeatureNames.addAll(Arrays.asList(aFeatureNames));
+ this.hiddenFeatureNames.addAll(Arrays.asList(aFeatureNames));
}
/**
@@ -650,7 +696,7 @@ public class CasAnnotationViewer extends
* to the same entity.
*/
public void setEntityResolver(EntityResolver aEntityResolver) {
- mEntityResolver = aEntityResolver;
+ this.entityResolver = aEntityResolver;
}
/**
@@ -665,7 +711,7 @@ public class CasAnnotationViewer extends
* to vary
*/
public void setConsistentColors(boolean aConsistent) {
- useConsistentColors = aConsistent;
+ this.useConsistentColors = aConsistent;
}
/**
@@ -676,8 +722,10 @@ public class CasAnnotationViewer extends
* true to put the viewer in right-to-left mode, false for left-to-right (the default).
*/
public void setRightToLeftTextOrientation(boolean aRightToLeft) {
- textPane.applyComponentOrientation(aRightToLeft ? ComponentOrientation.RIGHT_TO_LEFT
+ if (this.textPane != null) {
+ this.textPane.applyComponentOrientation(aRightToLeft ? ComponentOrientation.RIGHT_TO_LEFT
: ComponentOrientation.LEFT_TO_RIGHT);
+ }
}
/**
@@ -688,8 +736,8 @@ public class CasAnnotationViewer extends
* @param aHideUnselected
*/
public void setHideUnselectedCheckboxes(boolean aHideUnselected) {
- hideUnselectedCheckboxes = aHideUnselected;
- display();
+ this.hideUnselectedCheckBoxes = aHideUnselected;
+ this.display();
}
/**
@@ -698,60 +746,57 @@ public class CasAnnotationViewer extends
* @param aCAS
* the CSA to be viewed
*/
- @SuppressWarnings("unchecked")
public void setCAS(CAS aCAS) {
- cas = aCAS;
- stringType = cas.getTypeSystem().getType(CAS.TYPE_NAME_STRING);
- fsArrayType = cas.getTypeSystem().getType(CAS.TYPE_NAME_FS_ARRAY);
- // clear checkbox panel so it will be repopulated
- annotationCheckboxPanel.removeAll();
- entityCheckboxPanel.removeAll();
- typeToCheckBoxMap.clear();
- entityToCheckBoxMap.clear();
+ this.reset();
+ this.cas = aCAS;
+ this.typeSystem = this.cas.getTypeSystem();
+ this.stringType = this.typeSystem.getType(CAS.TYPE_NAME_STRING);
+ this.fsArrayType = this.typeSystem.getType(CAS.TYPE_NAME_FS_ARRAY);
// clear selected annotation details tree
- this.updateSelectedAnnotationTree(-1);
-
- // clear type to color map if color consistency is off
- if (!useConsistentColors) {
- typeColorMap.clear();
- // but reassign colors to high frequency types
- assignColors(highFrequencyTypes);
- }
-
- // clear boldface
- boldFaceKeyWords = new String[0];
- boldFaceSpans = new int[0];
+ this.initializeSofaSelectionPanel();
// enable or disable entity view depending on user's choice
this.viewModePanel.setVisible(entityViewEnabled);
+ // Instead of relying on the SofaSelectionComboBox itemChanged event to trigger the initial display,
+ // which does not necessarily need to happen unless we indeed switch over to different sofa,
+ // explicitly invoke display() here.
+ this.display();
+ }
+ @SuppressWarnings("unchecked")
+ private void initializeSofaSelectionPanel() {
// Populate sofa combo box with the names of all text Sofas in the CAS
- sofaSelectionComboBox.removeAllItems();
- Iterator<SofaFS> sofas = aCAS.getSofaIterator();
- Feature sofaIdFeat = aCAS.getTypeSystem().getFeatureByFullName(CAS.FEATURE_FULL_NAME_SOFAID);
- boolean nonDefaultSofaFound = false;
- while (sofas.hasNext()) {
- SofaFS sofa = sofas.next();
- if (sofa.getLocalStringData() != null) {
- String sofaId = sofa.getStringValue(sofaIdFeat);
- if (CAS.NAME_DEFAULT_SOFA.equals(sofaId)) {
- sofaId = "DEFAULT"; // make nicer display
- } else {
- nonDefaultSofaFound = true;
- }
- sofaSelectionComboBox.addItem(sofaId);
- // if this sofa matches the view passed to this method, select it
- CAS viewOfSofa = aCAS.getView(sofa);
- if (viewOfSofa == aCAS) {
- sofaSelectionComboBox.setSelectedIndex(sofaSelectionComboBox.getItemCount() - 1);
- }
+ if (this.sofaSelectionComboBox == null) {
+ return;
+ }
+ this.sofaSelectionComboBox.removeAllItems();
+ boolean hasNonDefaultSofa = false;
+ Feature sofaIdFeature = this.typeSystem.getFeatureByFullName(CAS.FEATURE_FULL_NAME_SOFAID);
+ FSIterator<SofaFS> sofaIterator = this.cas.getSofaIterator();
+ while (sofaIterator != null && sofaIterator.hasNext()) {
+ SofaFS sofa = sofaIterator.next();
+ if (sofa.getLocalStringData() == null) {
+ continue;
+ }
+ String sofaId = sofa.getStringValue(sofaIdFeature);
+ if (CAS.NAME_DEFAULT_SOFA.equals(sofaId)) {
+ sofaId = "DEFAULT"; // make nicer display
+ } else {
+ hasNonDefaultSofa = true;
+ }
+ this.sofaSelectionComboBox.addItem(sofaId);
+ // if this sofa matches the view passed to this method, select it
+ if (this.cas.getView(sofa) == this.cas) {
+ this.sofaSelectionComboBox.setSelectedIndex(this.sofaSelectionComboBox.getItemCount() - 1);
}
}
- if (sofaSelectionComboBox.getItemCount() == 0) {
+ if (this.sofaSelectionComboBox.getItemCount() == 0) {
throw new RuntimeException("This CAS contains no document to view.");
}
// make sofa selector visible if any text sofa other than the default was found
- sofaSelectionPanel.setVisible(nonDefaultSofaFound);
+ if (this.sofaSelectionPanel != null) {
+ this.sofaSelectionPanel.setVisible(hasNonDefaultSofa);
+ }
// Note that selection of the Sofa from the combo box happens during
// population, and that triggers the call to display() to display
@@ -759,6 +804,66 @@ public class CasAnnotationViewer extends
// display();
}
+ private void reset() {
+ // clear type to color map if color consistency is off
+ this.resetTypeColorMap();
+ this.resetTypeCheckBoxPanel();
+ this.resetEntityCheckBoxPanel();
+ this.resetSelectedAnnotationTree();
+
+ // clear boldface
+ this.boldFaceKeyWords = new String[0];
+ this.boldFaceSpans = new int[0];
+ }
+
+ private void resetSelectedAnnotationTree() {
+ if (this.selectedAnnotationTreeModel != null) {
+ DefaultMutableTreeNode root = (DefaultMutableTreeNode) this.selectedAnnotationTreeModel.getRoot();
+ if (root != null) {
+ root.removeAllChildren();
+ }
+ }
+ }
+
+ private void resetEntityCheckBoxPanel() {
+ if (this.entityToCheckBoxMap == null) {
+ this.entityToCheckBoxMap = new HashMap<Entity, JCheckBox>();
+ }
+ if (this.entityToCheckBoxMap.size() > 0) {
+ this.entityToCheckBoxMap.clear();
+ }
+ if (this.entityCheckboxPanel != null) {
+ this.entityCheckboxPanel.removeAll();
+ }
+ }
+
+ private void resetTypeCheckBoxPanel() {
+ // clear checkbox panel so it will be repopulated
+ if (this.typeToCheckBoxMap == null) {
+ this.typeToCheckBoxMap = new HashMap<Type, JCheckBox>();
+ }
+ if (this.typeToCheckBoxMap.size() > 0) {
+ this.typeToCheckBoxMap.clear();
+ }
+ if (this.annotationCheckboxPanel != null) {
+ this.annotationCheckboxPanel.removeAll();
+ }
+ }
+
+ private void resetTypeColorMap() {
+ if (this.typeColorMap == null) {
+ this.typeColorMap = new HashMap<String, Color>();
+ }
+ if (!this.useConsistentColors) {
+ if (this.typeColorMap.size() > 0) {
+ this.typeColorMap.clear();
+ }
+ if (this.highFrequencyTypes != null && this.highFrequencyTypes.size() > 0) {
+ this.assignTypeColors(this.highFrequencyTypes);
+ }
+ }
+ }
+
/**
* Causes the specified words to appear in boldface wherever they occur in the document. This is
* case-insensitive. Call this method after {@link #setCAS(CAS)}. It wil apply only to the current
@@ -768,8 +873,8 @@ public class CasAnnotationViewer extends
* array of words to highlight in boldface.
*/
public void applyBoldfaceToKeywords(String[] aWords) {
- boldFaceKeyWords = aWords;
- doBoldface();
+ this.boldFaceKeyWords = aWords;
+ this.doBoldFace();
}
/**
@@ -781,8 +886,8 @@ public class CasAnnotationViewer extends
* spans to appear in boldface (begin1, end1, begin2, end2, ...)
*/
public void applyBoldfaceToSpans(int[] aSpans) {
- boldFaceSpans = aSpans;
- doBoldface();
+ this.boldFaceSpans = aSpans;
+ this.doBoldFace();
}
/**
@@ -858,11 +963,14 @@ public class CasAnnotationViewer extends
* list of types not to be initially checked JMP
*/
public void assignCheckedFromList(List<String> aNotChecked) {
- Iterator<String> iterC = aNotChecked.iterator();
- while (iterC.hasNext()) {
- String typeName = iterC.next();
- // assign to list of types not to be initially checked
- typesNotChecked.add(typeName);
+ if (aNotChecked == null || aNotChecked.size() == 0) {
+ return;
+ }
+ if (this.typesNotChecked == null) {
+ this.typesNotChecked = new HashSet<String>();
+ }
+ for (String typeName : aNotChecked) {
+ this.typesNotChecked.add(typeName);
}
}
@@ -876,22 +984,32 @@ public class CasAnnotationViewer extends
*/
public void assignColorsFromList(List<Color> aColors, List<String> aTypeNames) {
// populate mTypeNameToColorMap
- Iterator<String> iter = aTypeNames.iterator();
- Iterator<Color> iterC = aColors.iterator();
- while (iter.hasNext()) {
- if (!iterC.hasNext())
- break;
- String typeName = (String) iter.next();
- Color color = (Color) iterC.next();
- // assign background color
- typeColorMap.put(typeName, color);
+ if (aColors == null || aColors.size() == 0 || aTypeNames == null || aTypeNames.size() == 0) {
+ return;
+ }
+ if (this.userTypes == null) {
+ this.userTypes = new ArrayList<String>();
+ }
+ if (this.userTypes.size() > 0) {
+ this.userTypes.clear();
+ }
+ if (this.typeColorMap == null) {
+ this.typeColorMap = new HashMap<String, Color>();
+ }
+ if (this.typeColorMap.size() > 0) {
+ this.typeColorMap.clear();
+ }
+ int colorCount = aColors.size();
+ for (int i = 0; i < aTypeNames.size(); i++) {
+ Color color = aColors.get(i % colorCount);
+ String inTypeName = aTypeNames.get(i);
+ this.typeColorMap.put(inTypeName, color);
+ this.userTypes.add(inTypeName);
}
-
- setUserTypes(aTypeNames);
// clear checkbox panel so it will be refreshed
- annotationCheckboxPanel.removeAll();
- typeToCheckBoxMap.clear();
+ this.annotationCheckboxPanel.removeAll();
+ this.typeToCheckBoxMap.clear();
}
/**
@@ -900,19 +1018,27 @@ public class CasAnnotationViewer extends
* @param aTypeNames
* list of type names
*/
- private void assignColors(List<String> aTypeNames) {
+ private void assignTypeColors(List<String> aTypeNames) {
// populate mTypeNameToColorMap
- Iterator<String> iter = aTypeNames.iterator();
- while (iter.hasNext()) {
- String typeName = iter.next();
- // assign background color
- Color c = COLORS[typeColorMap.size() % COLORS.length];
- typeColorMap.put(typeName, c);
+ if (aTypeNames == null || aTypeNames.size() == 0) {
+ return;
+ }
+
+ if (this.typeColorMap == null) {
+ this.typeColorMap = new HashMap<String, Color>();
+ }
+ for (String typeName : aTypeNames) {
+ if (!this.typeColorMap.containsKey(typeName)) {
+ // assign background color
+ this.typeColorMap.put(typeName, COLORS[this.typeColorMap.size() % COLORS.length]);
+ }
}
// clear checkbox panel so it will be refreshed
- annotationCheckboxPanel.removeAll();
- typeToCheckBoxMap.clear();
+ this.annotationCheckboxPanel.removeAll();
+ if (this.typeToCheckBoxMap != null) {
+ this.typeToCheckBoxMap.clear();
+ }
}
/**
@@ -921,49 +1047,49 @@ public class CasAnnotationViewer extends
*/
private void display() {
// remember split pane divider location so we can restore it later
- int dividerLoc = verticalSplitPane.getDividerLocation();
+ int dividerLocation = this.verticalSplitPane.getDividerLocation();
// remember caret pos and scroll position
- int caretPos = this.textPane.getCaretPosition();
+ int caretPosition = this.textPane.getCaretPosition();
int verticalScrollPos = this.textScrollPane.getVerticalScrollBar().getValue();
// type of display depends on whether we are in annotation or entity mode
- switch (viewMode) {
+ switch (this.viewMode) {
case MODE_ANNOTATIONS:
- displayAnnotations();
+ this.displayAnnotationView();
break;
case MODE_ENTITIES:
- displayEntities();
+ this.displayEntityView();
break;
}
// apply boldface to keywords and spans as indicated by user
- doBoldface();
+ this.doBoldFace();
// update the label of the Show/Hide Unselected Button
- if (hideUnselectedCheckboxes) {
- showHideUnselectedButton.setText("Show Unselected");
+ if (this.hideUnselectedCheckBoxes) {
+ this.showHideUnselectedButton.setText("Show Unselected");
} else {
- showHideUnselectedButton.setText("Hide Unselected");
+ this.showHideUnselectedButton.setText("Hide Unselected");
}
// reset scroll position
- textPane.setCaretPosition(caretPos);
- textScrollPane.getVerticalScrollBar().setValue(verticalScrollPos);
- textScrollPane.revalidate();
+ this.textPane.setCaretPosition(caretPosition);
+ this.textScrollPane.getVerticalScrollBar().setValue(verticalScrollPos);
+ this.textScrollPane.revalidate();
// reset split pane divider
- verticalSplitPane.setDividerLocation(dividerLoc);
+ this.verticalSplitPane.setDividerLocation(dividerLocation);
}
/**
* Creates the annotation display.
*/
- private void displayAnnotations() {
+ private void displayAnnotationView() {
// for speed, detach document from text pane before updating
- StyledDocument doc = (StyledDocument) textPane.getDocument();
+ StyledDocument doc = (StyledDocument) this.textPane.getDocument();
Document blank = new DefaultStyledDocument();
- textPane.setDocument(blank);
+ this.textPane.setDocument(blank);
// make sure annotationCheckboxPanel is showing
if (legendScrollPane.getViewport().getView() != annotationCheckboxPanel) {
@@ -973,158 +1099,162 @@ public class CasAnnotationViewer extends
// add text from CAS
try {
doc.remove(0, doc.getLength());
- doc.insertString(0, cas.getDocumentText(), new SimpleAttributeSet());
+ doc.insertString(0, this.cas.getDocumentText(), new SimpleAttributeSet());
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
// Iterate over annotations
- FSIterator<AnnotationFS> iter = cas.getAnnotationIndex().iterator();
- Hashtable<String, JCheckBox> checkBoxes = new Hashtable<String, JCheckBox>();
- Set<JCheckBox> checkBoxesDone = new HashSet<JCheckBox>();
- while (iter.isValid()) {
- AnnotationFS fs = iter.get();
- iter.moveToNext();
-
- Type type = fs.getType();
-
- // have we seen this type before?
- JCheckBox checkbox = (JCheckBox) typeToCheckBoxMap.get(type);
- if (checkbox == null) {
- // check that type should be displayed
- if ((displayedTypeNames == null || typeNamesContains(displayedTypeNames, type.getName()))
- && !typeNamesContains(hiddenTypeNames, type.getName())) {
- // if mTypeNameToColorMap exists, get color from there
- Color c = (Color) typeColorMap.get(type.getName());
- if (c == null) // assign next available color
- {
- c = COLORS[typeColorMap.size() % COLORS.length];
- typeColorMap.put(type.getName(), c);
- }
- // This next section required until priorities work properly
- // HashSet noCheckSet = new HashSet();
- String noCheckArray[] = {
- // "org.apache.jresporator.PROPER",
- // "DOCSTRUCT_ANNOT_TYPE",
- // "VOCAB_ANNOT_TYPE"
- };
- for (int i = 0; i < noCheckArray.length; i++) {
- typesNotChecked.add(noCheckArray[i]);
- }
- // end of section
+ AnnotationIndex<AnnotationFS> annotationIndex = this.cas.getAnnotationIndex();
+ if (annotationIndex == null) {
+ return;
+ }
+ FSIterator<AnnotationFS> annotationIterator = annotationIndex.iterator();
+ if (annotationIterator == null || !annotationIterator.hasNext()) {
+ return;
+ }
+ while (annotationIterator.hasNext()) {
+ this.processOneAnnotationInAnnotationView(doc, annotationIterator.next());
+ }
+ // now populate panel with checkboxes in order specified in user file. JMP
+ this.addTypeCheckBoxes();
+ // reattach document to text pane
+ this.textPane.setDocument(doc);
+ }
- // should type be initially selected?
- boolean selected = ((initiallySelectedTypeNames == null &&
- // document annotation is not initially selected in default case
- !CAS.TYPE_NAME_DOCUMENT_ANNOTATION.equals(type.getName()) && !typesNotChecked
- .contains(type.getName()) // priorities JMP
- ) || (initiallySelectedTypeNames != null && typeNamesContains(
- initiallySelectedTypeNames, type.getName())));
-
- // add checkbox
- checkbox = new JCheckBox(type.getShortName(), selected);
- checkbox.setToolTipText(type.getName());
- checkbox.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- display();
- }
- });
- checkbox.setBackground(c);
- // annotationCheckboxPanel.add(checkbox); do it later JMP
- checkBoxes.put(type.getName(), checkbox);
- checkBoxesDone.add(checkbox);
- // add to (Type, Checkbox) map
- typeToCheckBoxMap.put(type, checkbox);
- } else {
- // this type is not hidden, skip it
- continue;
+ private void addTypeCheckBoxes() {
+ if (this.typeToCheckBoxMap == null || this.typeToCheckBoxMap.size() == 0) {
+ return;
+ }
+
+ Map<String, JCheckBox> checkBoxMap = new HashMap<String, JCheckBox>();
+ Set<JCheckBox> checkBoxSet = new HashSet<JCheckBox>();
+ for (Type type : this.typeToCheckBoxMap.keySet()) {
+ JCheckBox typeCheckBox = this.typeToCheckBoxMap.get(type);
+ if (typeCheckBox.getParent() == this.annotationCheckboxPanel) {
+ // The check box is already added to the check box panel.
+ if (!typeCheckBox.isSelected() && this.hideUnselectedCheckBoxes) {
+ // But it is unselected and we choose to hide the unselected.
+ // Then it needs to be removed from the panel.
+ this.annotationCheckboxPanel.remove(typeCheckBox);
}
- }
- // if checkbox is checked, assign color to text
- if (checkbox.isSelected()) {
- int begin = fs.getBegin();
- int end = fs.getEnd();
-
- // Be careful of 0-length annotations and annotations that span the
- // entire document. In either of these cases, if we try to set
- // background color, it will set the input text style, which is not
- // what we want.
- if (begin == 0 && end == cas.getDocumentText().length()) {
- end--;
- }
-
- if (begin < end) {
- MutableAttributeSet attrs = new SimpleAttributeSet();
- StyleConstants.setBackground(attrs, checkbox.getBackground());
- doc.setCharacterAttributes(begin, end - begin, attrs, false);
+ } else {
+ // The check box is not yet added to the check box panel.
+ if (typeCheckBox.isSelected() || !this.hideUnselectedCheckBoxes) {
+ // The check box needs to be marked to be added.
+ checkBoxMap.put(type.getName(), typeCheckBox);
+ checkBoxSet.add(typeCheckBox);
}
}
}
-
- // now populate panel with checkboxes in order specified in user file. JMP
- List<String> aTypeNames = getUserTypes();
- if (aTypeNames != null) {
- Iterator<String> iterT = aTypeNames.iterator();
- while (iterT.hasNext()) {
- String typeName = iterT.next();
- JCheckBox cb = (JCheckBox) checkBoxes.get(typeName);
- if (cb != null) {
- annotationCheckboxPanel.add(cb);
- checkBoxesDone.remove(cb);
+ // First add the type check boxes for the types specified by user.
+ if (this.userTypes != null && this.userTypes.size() > 0) {
+ for (String userType : this.userTypes) {
+ JCheckBox typeCheckBox = checkBoxMap.get(userType);
+ if (typeCheckBox != null) {
+ this.annotationCheckboxPanel.add(typeCheckBox);
+ checkBoxSet.remove(typeCheckBox);
}
}
}
- // add additional checkboxes in alphabetical order
- List<JCheckBox> checkboxes = new LinkedList<JCheckBox>(checkBoxesDone);
- Collections.sort(checkboxes, new Comparator<JCheckBox>() {
- public int compare(JCheckBox o1, JCheckBox o2) {
- return o1.getText().toLowerCase().compareTo(
- o2.getText().toLowerCase());
+ // If we still have remaining type check boxes that need to be added,
+ // add them in sorted order.
+ if (checkBoxSet != null && checkBoxSet.size() > 0) {
+ List<JCheckBox> remainingCheckBoxes = new ArrayList<JCheckBox>(checkBoxSet);
+ Collections.sort(remainingCheckBoxes, new Comparator<JCheckBox>() {
+ @Override
+ public int compare(JCheckBox o1, JCheckBox o2) {
+ return o1.getText().toLowerCase().compareTo(o2.getText().toLowerCase());
+ }
+ });
+ for (JCheckBox checkBox : remainingCheckBoxes) {
+ this.annotationCheckboxPanel.add(checkBox);
}
- });
- Iterator<JCheckBox> iterC = checkboxes.iterator();
- while (iterC.hasNext()) {
- JCheckBox cb = iterC.next();
- annotationCheckboxPanel.add(cb);
}
+ }
- // add/remove checkboxes from display as determined by the
- // mHideUnselectedCheckboxes toggle
- Iterator<JCheckBox> cbIter = typeToCheckBoxMap.values().iterator();
- while (cbIter.hasNext()) {
- JCheckBox cb = cbIter.next();
- if (hideUnselectedCheckboxes && !cb.isSelected()) {
- if (cb.getParent() == annotationCheckboxPanel) {
- annotationCheckboxPanel.remove(cb);
- }
- } else if (cb.getParent() != annotationCheckboxPanel) {
- annotationCheckboxPanel.add(cb);
+ private void processOneAnnotationInAnnotationView(StyledDocument doc, AnnotationFS annotation) {
+ Type type = annotation.getType();
+ String typeName = type.getName();
+ // check that type should be displayed
+ if ((this.displayedTypeNames != null && !typeNamesContains(this.displayedTypeNames, typeName)) ||
+ (this.hiddenTypeNames != null && typeNamesContains(this.hiddenTypeNames, typeName))) {
+ return;
+ }
+ if (this.typeToCheckBoxMap == null) {
+ this.typeToCheckBoxMap = new HashMap<Type, JCheckBox>();
+ }
+ // have we seen this type before?
+ JCheckBox typeCheckBox = this.typeToCheckBoxMap.get(type);
+ if (typeCheckBox == null) {
+ // There is no type checkbox representing this annotation yet.
+ // if mTypeNameToColorMap exists, get color from there
+ if (this.typeColorMap == null) {
+ this.typeColorMap = new HashMap<String, Color>();
}
+ Color typeColor = this.typeColorMap.get(typeName);
+ if (typeColor == null) { // assign next available color
+ typeColor = COLORS[this.typeColorMap.size() % COLORS.length];
+ this.typeColorMap.put(typeName, typeColor);
+ }
+ // should type be initially selected?
+ // document annotation is not initially selected in default case
+ boolean selected = (this.initiallySelectedTypeNames == null &&
+ !CAS.TYPE_NAME_DOCUMENT_ANNOTATION.equals(typeName) && (this.typesNotChecked == null || !this.typesNotChecked.contains(typeName))) ||
+ (this.initiallySelectedTypeNames != null && typeNamesContains(this.initiallySelectedTypeNames, typeName));
+ // add checkbox
+ typeCheckBox = new JCheckBox(type.getShortName(), selected);
+ typeCheckBox.setToolTipText(typeName);
+ typeCheckBox.setBackground(typeColor);
+ typeCheckBox.setOpaque(true);
+ typeCheckBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ display();
+ }
+ });
+ this.typeToCheckBoxMap.put(type, typeCheckBox);
}
- // reattach document to text pane
- textPane.setDocument(doc);
+ // if checkbox is checked, assign color to text
+ if (typeCheckBox.isSelected()) {
+ int begin = annotation.getBegin();
+ int end = annotation.getEnd();
+
+ // Be careful of 0-length annotations and annotations that span the
+ // entire document. In either of these cases, if we try to set
+ // background color, it will set the input text style, which is not
+ // what we want.
+ if (begin == 0 && end == this.cas.getDocumentText().length()) {
+ end--;
+ }
+
+ if (begin < end) {
+ MutableAttributeSet attrs = new SimpleAttributeSet();
+ StyleConstants.setBackground(attrs, typeCheckBox.getBackground());
+ doc.setCharacterAttributes(begin, end - begin, attrs, false);
+ }
+ }
}
/**
* Creates the entity display.
*/
- private void displayEntities() {
+ private void displayEntityView() {
// for speed, detach document from text pane before updating
- StyledDocument doc = (StyledDocument) textPane.getDocument();
+ StyledDocument doc = (StyledDocument) this.textPane.getDocument();
Document blank = new DefaultStyledDocument();
- textPane.setDocument(blank);
+ this.textPane.setDocument(blank);
// make sure entityCheckboxPanel is showing
- if (legendScrollPane.getViewport().getView() != entityCheckboxPanel) {
- legendScrollPane.setViewportView(entityCheckboxPanel);
+ if (this.legendScrollPane.getViewport().getView() != this.entityCheckboxPanel) {
+ this.legendScrollPane.setViewportView(entityCheckboxPanel);
}
// add text from CAS
try {
doc.remove(0, doc.getLength());
- doc.insertString(0, cas.getDocumentText(), new SimpleAttributeSet());
+ doc.insertString(0, this.cas.getDocumentText(), new SimpleAttributeSet());
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
@@ -1139,68 +1269,73 @@ public class CasAnnotationViewer extends
} catch (CASException e) {
throw new RuntimeException(e);
}
- FSIterator<Annotation> iter = jcas.getAnnotationIndex().iterator();
- while (iter.isValid()) {
- Annotation annot = iter.get();
- iter.moveToNext();
-
- // find out what entity this annotation represents
- EntityResolver.Entity entity = mEntityResolver.getEntity(annot);
-
- //if not an entity, skip it
- if (entity == null)
- continue;
-
- // have we seen this entity before?
- JCheckBox checkbox = entityToCheckBoxMap.get(entity);
- if (checkbox == null) {
- // assign next available color
- Color c = COLORS[entityToCheckBoxMap.size() % COLORS.length];
- // add checkbox
- checkbox = new JCheckBox(entity.getCanonicalForm(), true);
- checkbox.setToolTipText(entity.getCanonicalForm());
- checkbox.addActionListener(new ActionListener() {
- @Override
- public void actionPerformed(ActionEvent e) {
- display();
- }
- });
- checkbox.setBackground(c);
- entityCheckboxPanel.add(checkbox);
- // add to (Entity, Checkbox) map
- entityToCheckBoxMap.put(entity, checkbox);
- }
-
- // if checkbox is checked, assign color to text
- if (checkbox.isSelected()) {
- int begin = annot.getBegin();
- int end = annot.getEnd();
- // be careful of 0-length annotation. If we try to set background color when there
- // is no selection, it will set the input text style, which is not what we want.
- if (begin != end) {
- MutableAttributeSet attrs = new SimpleAttributeSet();
- StyleConstants.setBackground(attrs, checkbox.getBackground());
- doc.setCharacterAttributes(begin, end - begin, attrs, false);
- }
- }
+ AnnotationIndex<Annotation> annotationIndex = jcas.getAnnotationIndex();
+ if (annotationIndex == null) {
+ return;
+ }
+ FSIterator<Annotation> annotationIterator = annotationIndex.iterator();
+ if (annotationIterator == null || !annotationIterator.hasNext()) {
+ return;
+ }
+ while (annotationIterator.hasNext()) {
+ this.processOneAnnotationInEntityView(doc, annotationIterator.next());
}
// add/remove checkboxes from display as determined by the
// mHideUnselectedCheckboxes toggle
- Iterator<JCheckBox> cbIter = entityToCheckBoxMap.values().iterator();
- while (cbIter.hasNext()) {
- JCheckBox cb = cbIter.next();
- if (hideUnselectedCheckboxes && !cb.isSelected()) {
- if (cb.getParent() == entityCheckboxPanel) {
- entityCheckboxPanel.remove(cb);
- }
- } else if (cb.getParent() != entityCheckboxPanel) {
- entityCheckboxPanel.add(cb);
+ for (JCheckBox entityCheckBox : this.entityToCheckBoxMap.values()) {
+ if (entityCheckBox.getParent() != this.entityCheckboxPanel &&
+ (entityCheckBox.isSelected() || !this.hideUnselectedCheckBoxes)) {
+ this.entityCheckboxPanel.add(entityCheckBox);
}
}
// reattach document to text pane
- textPane.setDocument(doc);
+ this.textPane.setDocument(doc);
+ }
+
+ private void processOneAnnotationInEntityView(StyledDocument doc, Annotation annotation) {
+ // find out what entity this annotation represents
+ EntityResolver.Entity entity = this.entityResolver.getEntity(annotation);
+ //if not an entity, skip it
+ if (entity == null) {
+ return;
+ }
+ if (this.entityToCheckBoxMap == null) {
+ this.entityToCheckBoxMap = new HashMap<Entity, JCheckBox>();
+ }
+ // have we seen this entity before?
+ JCheckBox entityCheckBox = this.entityToCheckBoxMap.get(entity);
+ if (entityCheckBox == null) {
+ // assign next available color
+ Color entityColor = COLORS[this.entityToCheckBoxMap.size() % COLORS.length];
+ // add checkbox
+ entityCheckBox = new JCheckBox(entity.getCanonicalForm(), true);
+ entityCheckBox.setToolTipText(entity.getCanonicalForm());
+ entityCheckBox.setBackground(entityColor);
+ entityCheckBox.setOpaque(true);
+ entityCheckBox.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ display();
+ }
+ });
+ this.entityCheckboxPanel.add(entityCheckBox);
+ // add to (Entity, Checkbox) map
+ this.entityToCheckBoxMap.put(entity, entityCheckBox);
+ }
+ // if checkbox is checked, assign color to text
+ if (entityCheckBox.isSelected()) {
+ int begin = annotation.getBegin();
+ int end = annotation.getEnd();
+ // be careful of 0-length annotation. If we try to set background color when there
+ // is no selection, it will set the input text style, which is not what we want.
+ if (begin != end) {
+ MutableAttributeSet attrs = new SimpleAttributeSet();
+ StyleConstants.setBackground(attrs, entityCheckBox.getBackground());
+ doc.setCharacterAttributes(begin, end - begin, attrs, false);
+ }
+ }
}
/**
@@ -1211,37 +1346,43 @@ public class CasAnnotationViewer extends
* point will be rendered in the tree.
*/
private void updateSelectedAnnotationTree(int aPosition) {
- DefaultMutableTreeNode root = (DefaultMutableTreeNode) this.selectedAnnotationTreeModel
- .getRoot();
+ if (this.cas == null || this.selectedAnnotationTreeModel == null) {
+ return;
+ }
+ JCas jcas = null;
+ try {
+ jcas = this.cas.getJCas();
+ } catch (CASException e) {
+ e.printStackTrace();
+ return;
+ }
+
+ DefaultMutableTreeNode root = (DefaultMutableTreeNode) this.selectedAnnotationTreeModel.getRoot();
root.removeAllChildren();
- FSIterator<AnnotationFS> annotIter = this.cas.getAnnotationIndex().iterator();
- while (annotIter.isValid()) {
- AnnotationFS annot = annotIter.get();
- // if (getPanePosition(annot.getBegin()) <= aPosition
- // && getPanePosition(annot.getEnd()) > aPosition)
- if (annot.getBegin() <= aPosition && annot.getEnd() > aPosition) {
- JCheckBox checkbox = typeToCheckBoxMap.get(annot.getType());
- if (checkbox != null && checkbox.isSelected()) {
- addAnnotationToTree(annot);
- }
- }
- // else if (getPanePosition(annot.getBegin()) > aPosition)
- else if (annot.getBegin() > aPosition)
+
+ AnnotationIndex<Annotation> annotationIndex = jcas.getAnnotationIndex();
+ if (annotationIndex == null) {
+ return;
+ }
+ FSIterator<Annotation> annotationIterator = annotationIndex.iterator();
+ if (annotationIterator == null || !annotationIterator.hasNext()) {
+ return;
+ }
+
+ while (annotationIterator.hasNext()) {
+ Annotation annotation = annotationIterator.next();
+ int begin = annotation.getBegin();
+ if (begin > aPosition) {
+ // Assuming all annotation objects are sorted by begin/end, if this one passed the given offset,
+ // there is no need to keep looking at the subsequent ones.
break;
- annotIter.moveToNext();
+ }
+ if (annotation.getEnd() > aPosition && this.isMatch(annotation)) {
+ // The annotation covers the given position (begins before and ends after the given position).
+ this.addAnnotationToTree(annotation);
+ }
}
this.selectedAnnotationTreeModel.nodeStructureChanged(root);
- // expand first level
- // int row = 0;
- // while (row < this.selectedAnnotationTree.getRowCount())
- // {
- // if (this.selectedAnnotationTree.getPathForRow(row).getPathCount() <= 2)
- // {
- // this.selectedAnnotationTree.expandRow(row);
- // }
- // row++;
- // }
-
// hmmm.. how to get scroll pane to resize properly??
this.selectedAnnotationTree.treeDidChange();
// this.selectedAnnotationTree.setPreferredSize(this.selectedAnnotationTree.getSize());
@@ -1250,6 +1391,38 @@ public class CasAnnotationViewer extends
}
/**
+ * Check if an annotation matches the filters set by the user. If true, the
+ * annotation will be added to the annotation tree display panel.
+ *
+ * @param annotation
+ * @return
+ */
+ private boolean isMatch(Annotation annotation) {
+ Type type = annotation.getType();
+ switch (this.viewMode) {
+ case MODE_ANNOTATIONS:
+ if (this.typeToCheckBoxMap == null || this.typeToCheckBoxMap.size() == 0) {
+ return false;
+ }
+ JCheckBox typeCheckBox = this.typeToCheckBoxMap.get(type);
+ return typeCheckBox != null && typeCheckBox.isSelected();
+ case MODE_ENTITIES:
+ if (this.entityToCheckBoxMap == null || this.entityToCheckBoxMap.size() == 0) {
+ return false;
+ }
+ Entity entity = this.entityResolver.getEntity(annotation);
+ if (entity == null) {
+ return false;
+ }
+ JCheckBox entityCheckBox = this.entityToCheckBoxMap.get(entity);
+ return entityCheckBox != null && entityCheckBox.isSelected();
+ default:
+ break;
+ }
+ return false;
+ }
+
+ /**
* Adds an annotation to the selected annotations tree. Annotations in the tree are grouped by
* type.
*
@@ -1257,16 +1430,15 @@ public class CasAnnotationViewer extends
* the annotation to add
*/
protected void addAnnotationToTree(AnnotationFS aAnnotation) {
- DefaultMutableTreeNode root = (DefaultMutableTreeNode) this.selectedAnnotationTreeModel
- .getRoot();
+ DefaultMutableTreeNode root = (DefaultMutableTreeNode) this.selectedAnnotationTreeModel.getRoot();
// try to find a node for the type
DefaultMutableTreeNode typeNode = null;
for (int i = 0; i < root.getChildCount(); i++) {
- DefaultMutableTreeNode child = (DefaultMutableTreeNode) root.getChildAt(i);
- if (aAnnotation.getType().equals(((TypeTreeNodeObject) child.getUserObject()).getType())) {
- typeNode = child;
- break;
- }
+ DefaultMutableTreeNode child = (DefaultMutableTreeNode) root.getChildAt(i);
+ if (aAnnotation.getType().equals(((TypeTreeNodeObject) child.getUserObject()).getType())) {
+ typeNode = child;
+ break;
+ }
}
if (typeNode == null) {
typeNode = new DefaultMutableTreeNode(new TypeTreeNodeObject(aAnnotation.getType()));
@@ -1274,129 +1446,181 @@ public class CasAnnotationViewer extends
}
// add annotation node
- DefaultMutableTreeNode annotationNode = new DefaultMutableTreeNode(new FsTreeNodeObject(
- aAnnotation, null));
+ DefaultMutableTreeNode annotationNode = new DefaultMutableTreeNode(new FsTreeNodeObject(aAnnotation, null));
typeNode.insert(annotationNode, 0);
// add child nodes for features
- addFeatureTreeNodes(annotationNode, aAnnotation);
+ this.addFeatureTreeNodes(annotationNode, aAnnotation);
}
private void addFeatureTreeNodes(DefaultMutableTreeNode aParentNode, FeatureStructure aFS) {
- List<Feature> aFeatures = aFS.getType().getFeatures();
- Iterator<Feature> iter = aFeatures.iterator();
- while (iter.hasNext()) {
- Feature feat = (Feature) iter.next();
- String featName = feat.getShortName();
+ List<Feature> features = aFS.getType().getFeatures();
+ if (features == null || features.size() == 0) {
+ return;
+ }
+
+ for (Feature feature : features) {
+ String featureName = feature.getShortName();
// skip hidden features
- if (hiddenFeatureNames.contains(featName)) {
+ if (this.hiddenFeatureNames != null && this.hiddenFeatureNames.contains(featureName)) {
continue;
}
// how we get feature value depends on feature's range type)
- String featVal = "null";
- Type rangeType = feat.getRange();
- String rangeTypeName = rangeType.getName();
- if (cas.getTypeSystem().subsumes(stringType, rangeType)) {
- featVal = aFS.getStringValue(feat);
- if (featVal == null) {
- featVal = "null";
- } else if (featVal.length() > 64) {
- featVal = featVal.substring(0, 64) + "...";
- }
- } else if (rangeType.isPrimitive()) {
- featVal = aFS.getFeatureValueAsString(feat);
- } else if (cas.getTypeSystem().subsumes(fsArrayType, rangeType)) {
- ArrayFS arrayFS = (ArrayFS) aFS.getFeatureValue(feat);
+ String featureValue = this.getFeatureValueInString(aFS, feature);
+ if (featureValue == null) {
+ continue;
+ }
+ if (featureValue.equalsIgnoreCase("*FSArray*")) {
+ // The feature value is an FSArray. Cannot render it as simple as "name=value".
+ ArrayFS arrayFS = (ArrayFS) aFS.getFeatureValue(feature);
if (arrayFS != null) {
- // Add featName = FSArray node, then add each array element as a child
- DefaultMutableTreeNode arrayNode = new DefaultMutableTreeNode(featName + " = FSArray");
+ // Create a node to represent the FSArray.
+ DefaultMutableTreeNode arrayNode = new DefaultMutableTreeNode(featureName + " = FSArray");
for (int i = 0; i < arrayFS.size(); i++) {
- FeatureStructure fsVal = arrayFS.get(i);
- if (fsVal != null) {
- // Add the FS node and a dummy child, so that user can expand it.
- // When user expands it, new nodes for feature values will be created.
- DefaultMutableTreeNode fsValNode = new DefaultMutableTreeNode(new FsTreeNodeObject(
- fsVal, featName));
- if (!fsVal.getType().getFeatures().isEmpty()) {
- fsValNode.add(new DefaultMutableTreeNode(null));
+ // Each FSArray element will be represented by a new tree node and added under the array node.
+ FeatureStructure featureStructure = arrayFS.get(i);
+ if (featureStructure != null) {
+ DefaultMutableTreeNode fsValueNode = new DefaultMutableTreeNode(
+ new FsTreeNodeObject(featureStructure, featureName));
+ if (!featureStructure.getType().getFeatures().isEmpty()) {
+ fsValueNode.add(new DefaultMutableTreeNode(null));
}
- arrayNode.add(fsValNode);
+ arrayNode.add(fsValueNode);
} else {
arrayNode.add(new DefaultMutableTreeNode("null"));
}
}
aParentNode.add(arrayNode);
- continue;
}
- } else if (rangeType.isArray()) // primitive array
- {
- String[] vals = null;
- if (CAS.TYPE_NAME_STRING_ARRAY.equals(rangeTypeName)) {
- StringArrayFSImpl arrayFS = (StringArrayFSImpl) aFS.getFeatureValue(feat);
- if (arrayFS != null)
- vals = arrayFS.toArray();
- } else if (CAS.TYPE_NAME_INTEGER_ARRAY.equals(rangeTypeName)) {
- IntArrayFSImpl arrayFS = (IntArrayFSImpl) aFS.getFeatureValue(feat);
- if (arrayFS != null)
- vals = arrayFS.toStringArray();
- } else if (CAS.TYPE_NAME_FLOAT_ARRAY.equals(rangeTypeName)) {
- FloatArrayFSImpl arrayFS = (FloatArrayFSImpl) aFS.getFeatureValue(feat);
- if (arrayFS != null)
- vals = arrayFS.toStringArray();
- } else if (CAS.TYPE_NAME_BOOLEAN_ARRAY.equals(rangeTypeName)) {
- BooleanArrayFSImpl arrayFS = (BooleanArrayFSImpl) aFS.getFeatureValue(feat);
- if (arrayFS != null)
- vals = arrayFS.toStringArray();
- } else if (CAS.TYPE_NAME_BYTE_ARRAY.equals(rangeTypeName)) {
- ByteArrayFSImpl arrayFS = (ByteArrayFSImpl) aFS.getFeatureValue(feat);
- if (arrayFS != null)
- vals = arrayFS.toStringArray();
- } else if (CAS.TYPE_NAME_SHORT_ARRAY.equals(rangeTypeName)) {
- ShortArrayFSImpl arrayFS = (ShortArrayFSImpl) aFS.getFeatureValue(feat);
- if (arrayFS != null)
- vals = arrayFS.toStringArray();
- } else if (CAS.TYPE_NAME_LONG_ARRAY.equals(rangeTypeName)) {
- LongArrayFSImpl arrayFS = (LongArrayFSImpl) aFS.getFeatureValue(feat);
- if (arrayFS != null)
- vals = arrayFS.toStringArray();
- }
- if (CAS.TYPE_NAME_DOUBLE_ARRAY.equals(rangeTypeName)) {
- DoubleArrayFSImpl arrayFS = (DoubleArrayFSImpl) aFS.getFeatureValue(feat);
- if (arrayFS != null)
- vals = arrayFS.toStringArray();
- }
- if (vals == null) {
- featVal = "null";
- } else {
- StringBuffer displayVal = new StringBuffer();
- displayVal.append('[');
- for (int i = 0; i < vals.length - 1; i++) {
- displayVal.append(vals[i]);
- displayVal.append(',');
- }
- if (vals.length > 0) {
- displayVal.append(vals[vals.length - 1]);
+ } else {
+ if (featureValue.equalsIgnoreCase("*FS*")) {
+ // The feature value is an annotation object. Cannot render it as simple as "name=value".
+ FeatureStructure featureStructure = aFS.getFeatureValue(feature);
+ if (featureStructure != null) {
+ // Need to create a node to represent the annotation.
+ DefaultMutableTreeNode fsValueNode = new DefaultMutableTreeNode(
+ new FsTreeNodeObject(featureStructure, featureName));
+ if (!featureStructure.getType().getFeatures().isEmpty()) {
+ fsValueNode.add(new DefaultMutableTreeNode(null));
+ }
+ aParentNode.add(fsValueNode);
}
- displayVal.append(']');
- featVal = displayVal.toString();
+ } else {
+ // The feature value can be rendered as simple as "name=value". There is no need to go down any further.
+ aParentNode.add(new DefaultMutableTreeNode(featureName + " = " + featureValue));
}
- } else
- // single feature value
- {
- FeatureStructure fsVal = aFS.getFeatureValue(feat);
- if (fsVal != null) {
- // Add the FS node and a dummy child, so that user can expand it.
- // When user expands it, new nodes for feature values will be created.
- DefaultMutableTreeNode fsValNode = new DefaultMutableTreeNode(new FsTreeNodeObject(fsVal,
- featName));
- if (!fsVal.getType().getFeatures().isEmpty()) {
- fsValNode.add(new DefaultMutableTreeNode(null));
- }
- aParentNode.add(fsValNode);
- continue;
+ }
+ }
+ }
+
+ /**
+ * Get feature value in string, if value is not another annotation and not
+ * an array of annotations.
+ *
+ * @param aFS
+ * @param feature
+ * @return
+ */
+ private String getFeatureValueInString(FeatureStructure aFS, Feature feature) {
+ if (this.cas == null || this.typeSystem == null || this.stringType == null || this.fsArrayType == null) {
+ return "null";
+ }
+
+ Type rangeType = feature.getRange();
+ if (this.typeSystem.subsumes(this.fsArrayType, rangeType)) {
+ // If the feature is an FSArray, cannot render it as simple as "name=value".
+ return "*FSArray*";
+ }
+ if (this.typeSystem.subsumes(this.stringType, rangeType)) {
+ return checkString(aFS.getStringValue(feature), "null", 64);
+ }
+ if (rangeType.isPrimitive()) {
+ return checkString(aFS.getFeatureValueAsString(feature), "null", 64);
+ }
+ if (rangeType.isArray()) {
+ String rangeTypeName = rangeType.getName();
+ String[] values = null;
+ if (CAS.TYPE_NAME_STRING_ARRAY.equals(rangeTypeName)) {
+ StringArrayFSImpl arrayFS = (StringArrayFSImpl) aFS.getFeatureValue(feature);
+ if (arrayFS != null) {
+ values = arrayFS.toArray();
+ }
+ } else if (CAS.TYPE_NAME_INTEGER_ARRAY.equals(rangeTypeName)) {
+ IntArrayFSImpl arrayFS = (IntArrayFSImpl) aFS.getFeatureValue(feature);
+ if (arrayFS != null) {
+ values = arrayFS.toStringArray();
+ }
+ } else if (CAS.TYPE_NAME_FLOAT_ARRAY.equals(rangeTypeName)) {
+ FloatArrayFSImpl arrayFS = (FloatArrayFSImpl) aFS.getFeatureValue(feature);
+ if (arrayFS != null) {
+ values = arrayFS.toStringArray();
+ }
+ } else if (CAS.TYPE_NAME_BOOLEAN_ARRAY.equals(rangeTypeName)) {
+ BooleanArrayFSImpl arrayFS = (BooleanArrayFSImpl) aFS.getFeatureValue(feature);
+ if (arrayFS != null) {
+ values = arrayFS.toStringArray();
+ }
+ } else if (CAS.TYPE_NAME_BYTE_ARRAY.equals(rangeTypeName)) {
+ ByteArrayFSImpl arrayFS = (ByteArrayFSImpl) aFS.getFeatureValue(feature);
+ if (arrayFS != null) {
+ values = arrayFS.toStringArray();
+ }
+ } else if (CAS.TYPE_NAME_SHORT_ARRAY.equals(rangeTypeName)) {
+ ShortArrayFSImpl arrayFS = (ShortArrayFSImpl) aFS.getFeatureValue(feature);
+ if (arrayFS != null) {
+ values = arrayFS.toStringArray();
+ }
+ } else if (CAS.TYPE_NAME_LONG_ARRAY.equals(rangeTypeName)) {
+ LongArrayFSImpl arrayFS = (LongArrayFSImpl) aFS.getFeatureValue(feature);
+ if (arrayFS != null) {
+ values = arrayFS.toStringArray();
+ }
+ } else if (CAS.TYPE_NAME_DOUBLE_ARRAY.equals(rangeTypeName)) {
+ DoubleArrayFSImpl arrayFS = (DoubleArrayFSImpl) aFS.getFeatureValue(feature);
+ if (arrayFS != null) {
+ values = arrayFS.toStringArray();
}
+ } else {
+ // Unknown array type.
+ }
+ if (values == null || values.length == 0) {
+ return "null";
}
- aParentNode.add(new DefaultMutableTreeNode(featName + " = " + featVal));
+
+ StringBuffer displayValue = new StringBuffer();
+ displayValue.append("[");
+ for (int i = 0; i < values.length - 1; i++) {
+ displayValue.append(values[i]);
+ displayValue.append(",");
+ }
+ displayValue.append(values[values.length - 1]);
+ displayValue.append("]");
+ return displayValue.toString();
}
+
+ // If none of the above, then it is an annotation object. Cannot render it as simple as "name=value".
+ return "*FS*";
+ }
+
+ /**
+ * Check if a string is null or longer than specified limit. If null, use
+ * default value. If longer than specified limit, take only the leading
+ * substring that would fit in the limit.
+ *
+ * @param stringValue
+ * @param defaultIfNull
+ * @param maxLength
+ * @return
+ */
+ private static String checkString(String stringValue, String defaultIfNull, int maxLength) {
+ if (stringValue == null) {
+ return defaultIfNull;
+ }
+
+ if (maxLength > 0 && stringValue.length() > maxLength) {
+ return stringValue.substring(0, maxLength) + "...";
+ }
+
+ return stringValue;
}
/**
@@ -1408,21 +1632,19 @@ public class CasAnnotationViewer extends
* A type name
* @return True iff name matches a name in type names
*/
- private boolean typeNamesContains(Set<String> names, String name) {
- if (names.contains(name))
+ private static boolean typeNamesContains(Set<String> names, String name) {
+ if (names.contains(name)) {
return true;
- else {
- Iterator<String> namesIterator = names.iterator();
- while (namesIterator.hasNext()) {
- String otherName = namesIterator.next();
- if (otherName.indexOf('*') != -1) {
- if (wildCardMatch(name, otherName)) {
- return true;
- }
- } else {
- if (otherName.equalsIgnoreCase(name)) {
- return true;
- }
+ }
+
+ for (String pattern : names) {
+ if (pattern.indexOf('*') != -1) {
+ if (wildCardMatch(name, pattern)) {
+ return true;
+ }
+ } else {
+ if (pattern.equalsIgnoreCase(name)) {
+ return true;
}
}
}
@@ -1432,29 +1654,33 @@ public class CasAnnotationViewer extends
/**
* Helper for {@link #typeNamesContains(HashSet, String)}.
*
- * @param s
+ * @param name
* A litteral string
* @param pattern
* A string that includes one or more *'s as wildcards
* @return True iff the string matches the pattern.
*/
- private boolean wildCardMatch(String s, String pattern) {
- StringBuffer regexpPatternBuffer = new StringBuffer();
+ private static boolean wildCardMatch(String name, String pattern) {
+ if (pattern == null || pattern.length() == 0) {
+ return false;
+ }
+ StringBuffer regex = new StringBuffer();
for (int i = 0; i < pattern.length(); i++) {
char c = pattern.charAt(i);
- if (c == '*')
- regexpPatternBuffer.append('.');
- else if (c == '.')
- regexpPatternBuffer.append('\\');
+ if (c == '*') {
+ regex.append('.');
+ }
+ if (c == '.') {
+ regex.append('\\');
+ }
if (Character.isLetter(c)) {
- regexpPatternBuffer.append('(').append(Character.toLowerCase(c)).append('|').append(
- Character.toUpperCase(c)).append(')');
+ regex.append('(').append(Character.toLowerCase(c)).append('|').append(Character.toUpperCase(c)).append(')');
} else {
- regexpPatternBuffer.append(c);
+ regex.append(c);
}
}
- return s.matches(new String(regexpPatternBuffer));
+ return name != null && name.length() > 0 && name.matches(new String(regex));
}
/**
@@ -1466,73 +1692,83 @@ public class CasAnnotationViewer extends
Dimension paneSize = new Dimension(d.width - insets.left - insets.right, d.height - insets.top
- insets.bottom);
- horizontalSplitPane.setPreferredSize(paneSize);
- horizontalSplitPane.setSize(paneSize);
+ this.horizontalSplitPane.setPreferredSize(paneSize);
+ this.horizontalSplitPane.setSize(paneSize);
}
/**
* Applies boldface as per the mBoldfaceKeywords and mBoldfaceSpans fields.
*/
- private void doBoldface() {
+ private void doBoldFace() {
// Keywords
- if (boldFaceKeyWords.length > 0) {
- // build regular expression
- StringBuffer regEx = new StringBuffer();
- for (int i = 0; i < boldFaceKeyWords.length; i++) {
- if (i > 0) {
- regEx.append('|');
- }
- regEx.append("\\b");
- String word = boldFaceKeyWords[i];
- for (int j = 0; j < word.length(); j++) {
- char c = word.charAt(j);
- if (Character.isLetter(c)) {
- regEx.append('[').append(Character.toLowerCase(c)).append(Character.toUpperCase(c))
- .append(']');
- } else if (c == '.' || c == '^' || c == '&' || c == '\\' || c == '(' || c == ')') {
- regEx.append('\\').append(c);
- } else {
- regEx.append('c');
- }
- }
- regEx.append("\\b");
- }
- // System.out.println("RegEx: " + regEx);
- Pattern pattern = Pattern.compile(regEx.toString());
- Matcher matcher = pattern.matcher(cas.getDocumentText());
- // match
- int pos = 0;
- while (matcher.find(pos)) {
- MutableAttributeSet attrs = new SimpleAttributeSet();
- StyleConstants.setBold(attrs, true);
- StyledDocument doc = (StyledDocument) textPane.getDocument();
- doc.setCharacterAttributes(matcher.start(), matcher.end() - matcher.start(), attrs, false);
+ this.doBoldFaceByKeyWords();
+ // Spans
+ this.doBoldFaceBySpans();
+ }
- if (pos == matcher.end()) // infinite loop check
- break;
- else
- pos = matcher.end();
- }
+ private void doBoldFaceBySpans() {
+ if (this.boldFaceSpans == null || this.boldFaceSpans.length == 0) {
+ return;
}
- // Spans
- int docLength = cas.getDocumentText().length();
- int len = boldFaceSpans.length;
- len -= len % 2; // to avoid ArrayIndexOutOfBoundsException if some numbskull passes in an
- // odd-length array
+ int docLength = this.cas.getDocumentText().length();
+ int spanLength = this.boldFaceSpans.length - (this.boldFaceSpans.length % 2);
int i = 0;
- while (i < len) {
- int begin = boldFaceSpans[i];
- int end = boldFaceSpans[i + 1];
- if (begin >= 0 && begin <= docLength && end >= 0 && end <= docLength) {
+ while (i < spanLength) {
+ int begin = this.boldFaceSpans[i];
+ int end = this.boldFaceSpans[i + 1];
+ if (begin >= 0 && begin <= docLength && end >= 0 && end <= docLength && begin < end) {
MutableAttributeSet attrs = new SimpleAttributeSet();
StyleConstants.setBold(attrs, true);
- StyledDocument doc = (StyledDocument) textPane.getDocument();
+ StyledDocument doc = (StyledDocument) this.textPane.getDocument();
doc.setCharacterAttributes(begin, end - begin, attrs, false);
}
i += 2;
}
}
+ private void doBoldFaceByKeyWords() {
+ if (this.boldFaceKeyWords == null || this.boldFaceKeyWords.length == 0) {
+ return;
+ }
+
+ // build regular expression
+ StringBuffer regex = new StringBuffer();
+ for (int i = 0; i < this.boldFaceKeyWords.length; i++) {
+ if (i > 0) {
+ regex.append('|');
+ }
+ regex.append("\\b");
+ String keyWord = this.boldFaceKeyWords[i];
+ for (int j = 0; j < keyWord.length(); j++) {
+ char c = keyWord.charAt(j);
+ if (Character.isLetter(c)) {
+ regex.append('[').append(Character.toLowerCase(c)).append(Character.toUpperCase(c)).append(']');
+ } else if (c == '.' || c == '^' || c == '&' || c == '\\' || c == '(' || c == ')') {
+ regex.append('\\').append(c);
+ } else {
+ regex.append(c);
+ }
+ }
+ regex.append("\\b");
+ }
+ Pattern pattern = Pattern.compile(regex.toString());
+ Matcher matcher = pattern.matcher(this.cas.getDocumentText());
+ // match
+ int pos = 0;
+ while (matcher.find(pos)) {
+ int begin = matcher.start();
+ int end = matcher.end();
+ MutableAttributeSet attrs = new SimpleAttributeSet();
+ StyleConstants.setBold(attrs, true);
+ StyledDocument doc = (StyledDocument) this.textPane.getDocument();
+ doc.setCharacterAttributes(begin, end - begin, attrs, false);
+ if (pos == end) { // infinite loop check
+ break;
+ }
+ pos = end;
+ }
+ }
+
/**
* Gets the selected annotation tree component.
*
@@ -1542,7 +1778,7 @@ public class CasAnnotationViewer extends
protected JTree getSelectedAnnotationTree() {
return this.selectedAnnotationTree;
}
-
+
/**
* Trivial entity resolver that's applied if the user turns on entity mode without
* specifying their own entity resolver. Returns the covered text as the canonical form,