001: package com.vividsolutions.jump.workbench.ui;
002:
003: import java.awt.geom.NoninvertibleTransformException;
004: import java.awt.geom.Point2D;
005: import java.util.*;
006: import com.vividsolutions.jts.geom.Envelope;
007: import com.vividsolutions.jump.util.StringUtil;
008: import com.vividsolutions.jump.feature.AttributeType;
009: import com.vividsolutions.jump.feature.Feature;
010: import com.vividsolutions.jump.geom.EnvelopeUtil;
011: import com.vividsolutions.jump.workbench.model.Layer;
012: import com.vividsolutions.jump.workbench.ui.cursortool.SpecifyFeaturesTool;
013:
014: /**
015: * To customize the LayerViewPanel's tooltips, call LayerViewPanel#setToolTipText.
016: * You can specify attribute names in curly brackets e.g. {fid}.
017: */
018: public class ToolTipWriter {
019: private boolean enabled = false;
020: private LayerViewPanel panel;
021:
022: public boolean isEnabled() {
023: return enabled;
024: }
025:
026: public void setEnabled(boolean enabled) {
027: this .enabled = enabled;
028: }
029:
030: public ToolTipWriter(LayerViewPanel panel) {
031: this .panel = panel;
032: }
033:
034: public String write(String template, Point2D mouseLocation) {
035: int PIXEL_BUFFER = 2;
036: if (!enabled) {
037: return null;
038: }
039: Map layerToSpecifiedFeaturesMap;
040: try {
041: layerToSpecifiedFeaturesMap = SpecifyFeaturesTool
042: .layerToSpecifiedFeaturesMap(panel
043: .getLayerManager().iterator(), EnvelopeUtil
044: .expand(new Envelope(panel.getViewport()
045: .toModelCoordinate(mouseLocation)),
046: PIXEL_BUFFER
047: / panel.getViewport()
048: .getScale()));
049: } catch (NoninvertibleTransformException e) {
050: return "";
051: }
052: if (layerToSpecifiedFeaturesMap.isEmpty()) {
053: return null;
054: }
055: if (template == null || template.trim().length() == 0) {
056: return writeDefaultToolTip(layerToSpecifiedFeaturesMap);
057: }
058: String toolTip = template;
059: for (Iterator i = extractAttributeNames(template).iterator(); i
060: .hasNext();) {
061: String attributeName = (String) i.next();
062: toolTip = StringUtil.replaceAll(toolTip, "{"
063: + attributeName + "}", findValue(attributeName,
064: layerToSpecifiedFeaturesMap));
065: }
066: return toolTip;
067: }
068:
069: private String writeDefaultToolTip(Map layerToSpecifiedFeaturesMap) {
070: Feature feature = (Feature) ((Collection) layerToSpecifiedFeaturesMap
071: .values().iterator().next()).iterator().next();
072: String toolTip = "<html>";
073: toolTip += format("FID", "" + feature.getID());
074: for (int i = 0; i < Math.min(4, feature.getSchema()
075: .getAttributeCount()); i++) {
076: if (feature.getSchema().getAttributeType(i) == AttributeType.GEOMETRY) {
077: continue;
078: }
079: toolTip += "<br>"
080: + format(feature.getSchema().getAttributeName(i),
081: feature.getAttribute(i));
082: }
083: toolTip += "</html>";
084: return toolTip;
085: }
086:
087: private String format(String name, Object value) {
088: return "<b>" + name + ":</b> " + value;
089: }
090:
091: private String findValue(String attributeName,
092: Map layerToSpecifiedFeaturesMap) {
093: for (Iterator i = layerToSpecifiedFeaturesMap.keySet()
094: .iterator(); i.hasNext();) {
095: Layer layer = (Layer) i.next();
096: for (int j = 0; j < layer.getFeatureCollectionWrapper()
097: .getFeatureSchema().getAttributeCount(); j++) {
098: if ("fid".equalsIgnoreCase(attributeName)) {
099: return ""
100: + ((Feature) ((Collection) layerToSpecifiedFeaturesMap
101: .get(layer)).iterator().next())
102: .getID();
103: }
104: if (layer.getFeatureCollectionWrapper()
105: .getFeatureSchema().getAttributeName(j)
106: .equalsIgnoreCase(attributeName)) {
107: return ""
108: + ((Feature) ((Collection) layerToSpecifiedFeaturesMap
109: .get(layer)).iterator().next())
110: .getAttribute(j);
111: }
112: }
113: }
114: return "";
115: }
116:
117: private Set extractAttributeNames(String template) {
118: TreeSet attributeNames = new TreeSet();
119: String currentAttributeName = "";
120: for (int i = 0; i < template.length(); i++) {
121: switch (template.charAt(i)) {
122: case '{':
123: currentAttributeName = "";
124: break;
125: case '}':
126: attributeNames.add(currentAttributeName.trim());
127: currentAttributeName = "";
128: break;
129: default:
130: currentAttributeName += template.charAt(i);
131: break;
132: }
133: }
134: return attributeNames;
135: }
136: }
|