Parent: [a7a9ff] (diff)

Download this file

AnnotationTrackView.java    232 lines (213 with data), 10.2 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/*
* Copyright 2013-2014 TECO - Karlsruhe Institute of Technology.
*
* This file is part of TACET.
*
* TACET is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* TACET is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with TACET. If not, see <http://www.gnu.org/licenses/>.
*/
package squirrel.view;
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import squirrel.model.Annotation;
import squirrel.model.FloatingpointAnnotation;
import squirrel.model.IntegerAnnotation;
import squirrel.model.LabelAnnotation;
import squirrel.model.ModelFacade;
import squirrel.model.TrainAnnotation;
import squirrel.model.io.DataColumn;
import squirrel.model.io.DataSource;
import squirrel.util.Range;
/**
* An instance of this class represents a single track of annotations.
*/
@SuppressWarnings("serial")
public class AnnotationTrackView extends TrackView {
/**
* The height of the room between the annotation and this component's
* border.
*/
private int insets = 2;
/** The shape of the round corners. */
private int arcWidth = 7;
private int arcHeight = 7;
/**
* The color of this component's background. Background is anything that is
* not covered by an annotation.
*/
private Color clrBackground = super.getBackground();
/** The color of an annotaition's background. */
private Color clrAnnotationBackground = Color.LIGHT_GRAY;
/** The color of an annotation's foreground. */
private Color clrAnnotationForeground = Color.BLACK;
/** The color used for the line surrounding an annotation. */
private Color clrContour = Color.BLACK;
private int annotationIndex;
/**
* Constructs a new instance of this class that displays the annotations
* from {@code model} that fall into the range between {@code rangeStart}
* and {@code rangeEnd}.
* @param model the instance that is used to obtain annotations
* @param index the track's index this instance draws
* @param startRange the range to be initially displayed by this instance.
*/
public AnnotationTrackView(ModelFacade model, int index, Range startRange) {
super(model, index, startRange);
DataSource<? extends DataColumn> source = model.getCurrentDataSource();
this.name = source.getDataColumn(index).getName();
super.setBackground(clrBackground);
setFocusable(true);
this.annotationIndex = source.toAnnotationIndex(index);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// Use the extended capabilities of the Graphics2D instance
Graphics2D g2D = (Graphics2D) g;
// Make use of antialiasing to smoothen the curves
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int height = super.getHeight() - 2 * insets;
int vs = translateTimestampToPixel(visibleExcerpt.getStart());
int ve = translateTimestampToPixel(visibleExcerpt.getEnd());
for (Annotation annotation : model.getAnnotations(visibleExcerpt, annotationIndex)) {
int as = translateTimestampToPixel(annotation.getStart());
int ae = translateTimestampToPixel(annotation.getEnd());
int de = ve - ae;
int ds = vs - as;
int x = as - vs;
if (x < 0) x = 0;
int y = insets;
int visibleWidth = computeVisibleWidth(annotation, ds, de);
// the middle part of the annotation
g2D.setColor(clrAnnotationBackground);
g2D.fillRect(x + arcWidth, y + 1, visibleWidth - 2 * arcWidth, height);
g2D.fillRect(x, y + arcHeight, arcWidth, height - 2 * arcHeight);
g2D.fillRect(x + visibleWidth - arcWidth, y + arcHeight, arcWidth, height - 2 * arcHeight);
g2D.setColor(clrContour);
g2D.drawLine(x + arcWidth, y, x + visibleWidth - arcWidth, y);
g2D.drawLine(x + arcWidth, y + height, x + visibleWidth - arcWidth, y + height);
if (de > 0) { // round on the right
g2D.setColor(clrAnnotationBackground);
g2D.fillArc(x + visibleWidth - 2 * arcWidth, y, 2 * arcWidth, 2 * arcHeight, 0, 90);
g2D.fillArc(x + visibleWidth - 2 * arcWidth, y + height - 2 * arcHeight, 2 * arcWidth, 2 * arcHeight, 0, -90);
g2D.setColor(clrContour);
g2D.drawArc(x + visibleWidth - 2 * arcWidth, y, 2 * arcWidth, 2 * arcHeight, 0, 90);
g2D.drawArc(x + visibleWidth - 2 * arcWidth, y + height - 2 * arcHeight, 2 * arcWidth, 2 * arcHeight, 0, -90);
g2D.drawLine(x + visibleWidth, y + arcHeight, x + visibleWidth, y + height - arcHeight);
}
if (ds < 0) { // round on the left
g2D.setColor(clrAnnotationBackground);
g2D.fillArc(x, y, 2 * arcWidth, 2 * arcHeight, 90, 90);
g2D.fillArc(x, y + height - 2 * arcHeight, 2 * arcWidth, 2 * arcHeight, -90, -90);
g2D.setColor(clrContour);
g2D.drawArc(x, y, 2 * arcWidth, 2 * arcHeight, 90, 90);
g2D.drawArc(x, y + height - 2 * arcHeight, 2 * arcWidth, 2 * arcHeight, -90, -90);
g2D.drawLine(x, y + arcHeight, x, y + height - arcHeight);
}
if (de < 0) { // cut-off on the right
g2D.setColor(clrContour);
g2D.drawLine(x + visibleWidth - arcWidth, y, x + visibleWidth, y);
g2D.drawLine(x + visibleWidth - arcWidth, y + height, x + visibleWidth, y + height);
g2D.setColor(clrAnnotationBackground);
g2D.fillRect(x + visibleWidth - arcWidth, y + 1, arcWidth + 1, height - 1);
}
if (ds > 0) { // cut-off on the left
g2D.setColor(clrContour);
g2D.drawLine(x, y, x + arcWidth, y);
g2D.drawLine(x, y + height, x + arcHeight, y + height);
g2D.setColor(clrAnnotationBackground);
g2D.fillRect(x, y + 1, arcWidth, height - 1);
}
g2D.setColor(clrAnnotationForeground);
// Center the text to be drawn into the current rectangle.
drawCenteredString(g2D, makePrintable(annotation), height, x, visibleWidth);
}
}
/**
* Calculates the visible width of the @code annotation
*
* @param annotation - the annotation to calculate the width of
* @param diffStart
* @param diffEnd
* @return
*/
private int computeVisibleWidth(Annotation annotation, int diffStart, int diffEnd) {
int visibleWidth = 0;
if (diffStart < 0 && diffEnd > 0)
visibleWidth = translateTimestampToPixel(annotation.getEnd()) -
translateTimestampToPixel(annotation.getStart());
else if (diffStart > 0 && diffEnd > 0)
visibleWidth = translateTimestampToPixel(annotation.getEnd()) -
translateTimestampToPixel(visibleExcerpt.getStart());
else if (diffStart < 0 && diffEnd < 0)
visibleWidth = translateTimestampToPixel(visibleExcerpt.getEnd()) -
translateTimestampToPixel(annotation.getStart());
else if (diffStart > 0 && diffEnd < 0)
visibleWidth = translateTimestampToPixel(visibleExcerpt.getEnd()) -
translateTimestampToPixel(visibleExcerpt.getStart());
return visibleWidth;
}
/**
* Draws the centred label of the annotation
* @param g2D
* @param label - Name of the annotation
* @param height - height of an annotation track
* @param start - x coordinate where the annotation starts
* @param visibleWidth - width of the visible part of the anntotation
*/
private void drawCenteredString(Graphics2D g2D, String label, int height, int start,
int visibleWidth) {
FontMetrics fm = g2D.getFontMetrics();
int vStringInsets = insets + ((height - fm.getDescent()) / 2);
int hStringInsets = (visibleWidth - fm.stringWidth(label)) / 2;
g2D.drawString(label, start + hStringInsets, fm.getAscent() + vStringInsets - 5);
}
/**
* Analyses the annotation an returns a lable depending of which type of annotation it is
* @param annot - an annotation
* @return label/name of the annotation which will be painted on the annotation box
*/
private String makePrintable(Annotation annot) {
if (annot instanceof IntegerAnnotation) {
return String.valueOf(((IntegerAnnotation) annot).getValue());
} else if (annot instanceof FloatingpointAnnotation) {
return String.valueOf(((FloatingpointAnnotation) annot).getValue());
} else if (annot instanceof LabelAnnotation) {
return ((LabelAnnotation) annot).getLabel();
} else if (annot instanceof TrainAnnotation) {
return (annot.toValue());
}
return "-";
}
@Override
public boolean isOptimizedDrawingEnabled() {
return true;
}
@Override
public String toString() {
return String.format("%d:[%d-%d]", index, visibleExcerpt.getStart(),
visibleExcerpt.getEnd());
}
@Override
public long translatePixelToTimestamp(int x) {
return (long) ((double) visibleExcerpt.getDistance() / this.getWidth() * x) + visibleExcerpt.getStart();
}
@Override
public int translateTimestampToPixel(long timestamp) {
return (int) ((double) getWidth() / visibleExcerpt.getDistance() * (timestamp - visibleExcerpt.getStart()));
}
}