Changeset 29981 in osm for applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap
- Timestamp:
- 2013-09-27T20:35:14+02:00 (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/gui/ElevationProfilePanel.java
r29976 r29981 1 1 /** 2 * This program is free software: you can redistribute it and/or modify it under 3 * the terms of the GNU General Public License as published by the 4 * Free Software Foundation, either version 3 of the License, or 5 * (at your option) any later version. 2 * This program is free software: you can redistribute it and/or modify it under 3 * the terms of the GNU General Public License as published by the 4 * Free Software Foundation, either version 3 of the License, or 5 * (at your option) any later version. 6 6 * 7 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 8 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 9 * See the GNU General Public License for more details. 7 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 8 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 9 * See the GNU General Public License for more details. 10 10 * 11 * You should have received a copy of the GNU General Public License along with this program. 11 * You should have received a copy of the GNU General Public License along with this program. 12 12 * If not, see <http://www.gnu.org/licenses/>. 13 13 */ … … 48 48 */ 49 49 public class ElevationProfilePanel extends JPanel implements ComponentListener, MouseMotionListener { 50 /** 51 * Serial version UID 52 */ 53 private static final long serialVersionUID = -7343429725259575319L; 54 private IElevationModel model; 55 private Rectangle plotArea; 56 private IElevationProfileRenderer renderer = new DefaultElevationProfileRenderer(); 57 private int selectedIndex = -1; 58 private List<IElevationProfileSelectionListener> selectionChangedListeners = new ArrayList<IElevationProfileSelectionListener>(); 59 private boolean isPainting; 60 private int step = 0; 61 62 /** 63 * Constructs a new ElevationProfilePanel with the given elevation profile. 64 * @param profile The elevation profile to show in the panel. 65 */ 66 public ElevationProfilePanel(IElevationModel profile) { 67 super(); 68 this.model = profile; 69 setDoubleBuffered(true); 70 setBackground(Color.WHITE); 71 createOrUpdatePlotArea(); 72 addComponentListener(this); 73 addMouseMotionListener(this); 74 75 Font lFont = getFont().deriveFont(9.0f); 76 setFont(lFont); 77 } 78 79 /** 80 * Gets the elevation profile instance. 81 * @return 82 */ 83 public IElevationModel getProfile() { 84 return model; 85 } 86 87 /** 88 * Sets the new elevation profile instance. 89 * @param model 90 */ 91 public void setElevationModel(IElevationModel model) { 92 if (this.model != model) { 93 this.model = model; 94 invalidate(); 50 /** 51 * Serial version UID 52 */ 53 private static final long serialVersionUID = -7343429725259575319L; 54 private IElevationModel model; 55 private Rectangle plotArea; 56 private final IElevationProfileRenderer renderer = new DefaultElevationProfileRenderer(); 57 private int selectedIndex = -1; 58 private final List<IElevationProfileSelectionListener> selectionChangedListeners = new ArrayList<IElevationProfileSelectionListener>(); 59 private boolean isPainting; 60 private int step = 0; 61 62 /** 63 * Constructs a new ElevationProfilePanel with the given elevation profile. 64 * @param profile The elevation profile to show in the panel. 65 */ 66 public ElevationProfilePanel(IElevationModel profile) { 67 super(); 68 this.model = profile; 69 setDoubleBuffered(true); 70 setBackground(Color.WHITE); 71 createOrUpdatePlotArea(); 72 addComponentListener(this); 73 addMouseMotionListener(this); 74 75 Font lFont = getFont().deriveFont(9.0f); 76 setFont(lFont); 77 } 78 79 /** 80 * Gets the elevation profile instance. 81 * @return 82 */ 83 public IElevationModel getProfile() { 84 return model; 85 } 86 87 /** 88 * Sets the new elevation profile instance. 89 * @param model 90 */ 91 public void setElevationModel(IElevationModel model) { 92 if (this.model != model) { 93 this.model = model; 94 invalidate(); 95 } 96 } 97 98 /** 99 * Gets the plot area coordinates. 100 * @return 101 */ 102 public Rectangle getPlotArea() { 103 return plotArea; 104 } 105 106 /** 107 * Sets the plot area coordinates. 108 * @param plotArea 109 */ 110 public void setPlotArea(Rectangle plotArea) { 111 this.plotArea = plotArea; 112 } 113 114 /** 115 * Gets the selected index of the bar. 116 * @return 117 */ 118 public int getSelectedIndex() { 119 return selectedIndex; 120 } 121 122 /** 123 * Sets the selected index of the bar. 124 * @param selectedIndex 125 */ 126 public void setSelectedIndex(int selectedIndex) { 127 this.selectedIndex = selectedIndex; 128 129 if (model != null) { 130 model.setCurrentProfile(selectedIndex); 131 } 132 } 133 134 /** 135 * Gets the selected (highlighted) way point. 136 * @return The selected way point or null, if no way point is selected. 137 */ 138 public WayPoint getSelectedWayPoint() { 139 if (model == null) return null; 140 141 IElevationProfile profile = model.getCurrentProfile(); 142 143 int selWp = this.selectedIndex * step; 144 if (profile != null && profile.getWayPoints() != null && selWp > 0 && profile.getWayPoints().size() > selWp) { 145 return profile.getWayPoints().get(selWp); 146 } else { 147 return null; 148 } 149 } 150 151 /** 152 * Adds a selection listener. 153 * @param listener The listener instance to add. 154 */ 155 public void addSelectionListener(IElevationProfileSelectionListener listener) { 156 if (listener == null) return; 157 158 selectionChangedListeners.add(listener); 159 } 160 161 /** 162 * Removes a selection listener from the list. 163 * @param listener The listener instance to remove. 164 */ 165 public void removeSelectionListener(IElevationProfileSelectionListener listener) { 166 if (listener == null) return; 167 168 selectionChangedListeners.remove(listener); 169 } 170 171 /** 172 * Removes all selection listeners. 173 */ 174 public void removeAllSelectionListeners() { 175 selectionChangedListeners.clear(); 176 } 177 178 protected void fireSelectionChanged(WayPoint selWayPoint) { 179 for (IElevationProfileSelectionListener listener : selectionChangedListeners) { 180 listener.selectedWayPointChanged(selWayPoint); 181 } 182 } 183 184 /* (non-Javadoc) 185 * @see javax.swing.JComponent#paint(java.awt.Graphics) 186 */ 187 @Override 188 public void paint(Graphics g) { 189 isPainting = true; 190 191 try { 192 super.paint(g); 193 createOrUpdatePlotArea(); 194 int y1 = getPlotBottom(); 195 196 g.setColor(Color.DARK_GRAY); 197 g.drawLine(plotArea.x, plotArea.y, plotArea.x, plotArea.y 198 + plotArea.height); 199 g.drawLine(plotArea.x, plotArea.y + plotArea.height, plotArea.x 200 + plotArea.width, plotArea.y + plotArea.height); 201 202 203 if (model != null) { 204 IElevationProfile profile = model.getCurrentProfile(); 205 if (profile != null && profile.hasElevationData()) { 206 drawAlignedString(formatDate(profile.getStart()), 5, y1 + 5, 207 TextAlignment.Left, g); 208 drawAlignedString(formatDate(profile.getEnd()), 209 getPlotRight(), y1 + 5, TextAlignment.Right, g); 210 211 212 drawProfile(g); 213 drawElevationLines(g); 214 } else { 215 // No profile or profile supports no elevation data 216 drawAlignedString(tr("(No elevation data)"), getPlotHCenter(), 217 getPlotVCenter(), TextAlignment.Centered, g); 95 218 } 96 } 97 98 /** 99 * Gets the plot area coordinates. 100 * @return 101 */ 102 public Rectangle getPlotArea() { 103 return plotArea; 104 } 105 106 /** 107 * Sets the plot area coordinates. 108 * @param plotArea 109 */ 110 public void setPlotArea(Rectangle plotArea) { 111 this.plotArea = plotArea; 112 } 113 114 /** 115 * Gets the selected index of the bar. 116 * @return 117 */ 118 public int getSelectedIndex() { 119 return selectedIndex; 120 } 121 122 /** 123 * Sets the selected index of the bar. 124 * @param selectedIndex 125 */ 126 public void setSelectedIndex(int selectedIndex) { 127 this.selectedIndex = selectedIndex; 128 129 if (model != null) { 130 model.setCurrentProfile(selectedIndex); 131 } 132 } 133 134 /** 135 * Gets the selected (highlighted) way point. 136 * @return The selected way point or null, if no way point is selected. 137 */ 138 public WayPoint getSelectedWayPoint() { 139 if (model == null) return null; 140 141 IElevationProfile profile = model.getCurrentProfile(); 142 143 int selWp = this.selectedIndex * step; 144 if (profile != null && profile.getWayPoints() != null && selWp > 0 && profile.getWayPoints().size() > selWp) { 145 return profile.getWayPoints().get(selWp); 146 } else { 147 return null; 148 } 149 } 150 151 /** 152 * Adds a selection listener. 153 * @param listener The listener instance to add. 154 */ 155 public void addSelectionListener(IElevationProfileSelectionListener listener) { 156 if (listener == null) return; 157 158 selectionChangedListeners.add(listener); 159 } 160 161 /** 162 * Removes a selection listener from the list. 163 * @param listener The listener instance to remove. 164 */ 165 public void removeSelectionListener(IElevationProfileSelectionListener listener) { 166 if (listener == null) return; 167 168 selectionChangedListeners.remove(listener); 169 } 170 171 /** 172 * Removes all selection listeners. 173 */ 174 public void removeAllSelectionListeners() { 175 selectionChangedListeners.clear(); 176 } 177 178 protected void fireSelectionChanged(WayPoint selWayPoint) { 179 for (IElevationProfileSelectionListener listener : selectionChangedListeners) { 180 listener.selectedWayPointChanged(selWayPoint); 181 } 182 } 183 184 /* (non-Javadoc) 185 * @see javax.swing.JComponent#paint(java.awt.Graphics) 186 */ 187 @Override 188 public void paint(Graphics g) { 189 isPainting = true; 190 191 try { 192 super.paint(g); 193 createOrUpdatePlotArea(); 194 int y1 = getPlotBottom(); 195 196 g.setColor(Color.DARK_GRAY); 197 g.drawLine(plotArea.x, plotArea.y, plotArea.x, plotArea.y 198 + plotArea.height); 199 g.drawLine(plotArea.x, plotArea.y + plotArea.height, plotArea.x 200 + plotArea.width, plotArea.y + plotArea.height); 201 202 203 if (model != null) { 204 IElevationProfile profile = model.getCurrentProfile(); 205 if (profile != null && profile.hasElevationData()) { 206 drawAlignedString(formatDate(profile.getStart()), 5, y1 + 5, 207 TextAlignment.Left, g); 208 drawAlignedString(formatDate(profile.getEnd()), 209 getPlotRight(), y1 + 5, TextAlignment.Right, g); 210 211 212 drawProfile(g); 213 drawElevationLines(g); 214 } else { 215 // No profile or profile supports no elevation data 216 drawAlignedString(tr("(No elevation data)"), getPlotHCenter(), 217 getPlotVCenter(), TextAlignment.Centered, g); 218 } 219 } 220 } finally { 221 isPainting = false; 222 } 223 } 224 225 /** 226 * Draw a string with a specified alignment. 227 * @param s The text to display. 228 * @param x The x coordinate. 229 * @param y The y coordinate. 230 * @param align The text alignment. 231 * @param g The graphics context. 232 * @return The resulting rectangle of the drawn string. 233 */ 234 private Rectangle drawAlignedString(String s, int x, int y, 235 TextAlignment align, Graphics g) { 236 FontMetrics fm = g.getFontMetrics(); 237 int w = fm.stringWidth(s); 238 int h = fm.getHeight(); 239 240 int xoff = w / 2; 241 int yoff = h / 2; 242 243 if (align == TextAlignment.Left) { 244 xoff = 0; 245 } 246 if (align == TextAlignment.Right) { 247 xoff = w; 248 } 249 250 g.drawString(s, x - xoff, y + yoff); 251 252 return new Rectangle(x - xoff, y - yoff, w, h); 253 } 254 255 /** 256 * Draw a string which is horizontally centered around (x,y). 257 * @param s The text to display. 258 * @param x The x coordinate. 259 * @param y The y coordinate. 260 * @param g The graphics context. 261 * @return The resulting rectangle of the drawn string. 262 219 } 220 } finally { 221 isPainting = false; 222 } 223 } 224 225 /** 226 * Draw a string with a specified alignment. 227 * @param s The text to display. 228 * @param x The x coordinate. 229 * @param y The y coordinate. 230 * @param align The text alignment. 231 * @param g The graphics context. 232 * @return The resulting rectangle of the drawn string. 233 */ 234 private Rectangle drawAlignedString(String s, int x, int y, 235 TextAlignment align, Graphics g) { 236 FontMetrics fm = g.getFontMetrics(); 237 int w = fm.stringWidth(s); 238 int h = fm.getHeight(); 239 240 int xoff = w / 2; 241 int yoff = h / 2; 242 243 if (align == TextAlignment.Left) { 244 xoff = 0; 245 } 246 if (align == TextAlignment.Right) { 247 xoff = w; 248 } 249 250 g.drawString(s, x - xoff, y + yoff); 251 252 return new Rectangle(x - xoff, y - yoff, w, h); 253 } 254 255 /** 256 * Draw a string which is horizontally centered around (x,y). 257 * @param s The text to display. 258 * @param x The x coordinate. 259 * @param y The y coordinate. 260 * @param g The graphics context. 261 * @return The resulting rectangle of the drawn string. 262 263 263 private void drawHCenteredString(String s, int x, int y, Graphics g) { 264 264 drawAlignedString(s, x, y, TextAlignment.Centered, g); 265 265 }*/ 266 266 267 /** 268 * Formats the date in a predefined manner: "21. Oct 2010, 12:10". 269 * @param date 270 * @return 271 */ 272 private String formatDate(Date date) { 273 Format formatter = new SimpleDateFormat("d MMM yy, HH:mm"); 274 275 return formatter.format(date); 276 } 277 278 /** 279 * Helper function to draw elevation axes. 280 * @param g 281 */ 282 private void drawElevationLines(Graphics g) { 283 IElevationProfile profile = model.getCurrentProfile(); 284 285 double diff = profile.getHeightDifference(); 286 287 if (diff == 0.0) { 288 return; 289 } 290 291 double z10 = Math.floor(Math.log10(diff)); 292 double scaleUnit = Math.pow(10, z10); // scale unit, e. g. 100 for 293 // values below 1000 294 295 int upperLimit = (int) (Math.round(Math.ceil(profile.getMaxHeight() 296 / scaleUnit)) * scaleUnit); 297 int lowerLimit = (int) (Math.round(Math.floor(profile.getMinHeight() 298 / scaleUnit)) * scaleUnit); 299 int su = (int) scaleUnit; 300 301 for (int i = lowerLimit; i <= upperLimit; i += su) { 302 int yLine = getYForEelevation(i); 303 304 // check bounds 305 if (yLine <= getPlotBottom() && yLine >= getPlotTop()) { 306 String txt = ElevationHelper.getElevationText(i); 307 308 Rectangle r = drawAlignedString(txt, getPlotHCenter(), yLine - 2, 309 TextAlignment.Right, g); 310 r.grow(2, 2); 311 312 // Draw left and right line segment 313 g.drawLine(getPlotLeftAxis(), yLine, r.x, 314 yLine); 315 g.drawLine(r.x + r.width, yLine, getPlotRight(), 316 yLine); 317 // Draw label with shadow 318 g.setColor(Color.WHITE); 319 drawAlignedString(txt, getPlotHCenter() + 1, yLine - 1, 320 TextAlignment.Right, g); 321 g.setColor(Color.BLACK); 322 drawAlignedString(txt, getPlotHCenter(), yLine - 2, 323 TextAlignment.Right, g); 324 } 325 } 326 } 327 328 /** 329 * Gets the x value of the left border for axes (slightly smaller than the 330 * left x). 331 * 332 * @return 333 */ 334 private int getPlotLeftAxis() { 335 return plotArea.x - 3; 336 } 337 338 /** 339 * Gets the x value of the left border. 340 * 341 * @return 342 */ 343 private int getPlotLeft() { 344 return plotArea.x + 1; 345 } 346 347 /** 348 * Gets the horizontal center coordinate (mid between left and right x). 349 * 350 * @return 351 */ 352 private int getPlotHCenter() { 353 return (getPlotLeft() + getPlotRight()) / 2; 354 } 355 356 /** 357 * Gets the vertical center coordinate (mid between top and bottom y). 358 * 359 * @return 360 */ 361 private int getPlotVCenter() { 362 return (getPlotTop() + getPlotBottom()) / 2; 363 } 364 365 /** 366 * Gets the x value of the right border. 367 * 368 * @return 369 */ 370 private int getPlotRight() { 371 return plotArea.x + plotArea.width - 1; 372 } 373 374 private int getPlotBottom() { 375 return plotArea.y + plotArea.height - 1; 376 } 377 378 private int getPlotTop() { 379 return plotArea.y + 1; 380 } 381 382 /** 383 * Gets for an elevation value the according y coordinate in the plot area. 384 * 385 * @param elevation 386 * @return The y coordinate in the plot area. 387 */ 388 private int getYForEelevation(int elevation) { 389 int y1 = getPlotBottom(); 390 391 IElevationProfile profile = model.getCurrentProfile(); 392 393 if (!profile.hasElevationData()) { 394 return y1; 395 } 396 397 double diff = profile.getHeightDifference(); 398 399 return y1 - (int) Math.round(((elevation - profile.getMinHeight()) / diff * plotArea.height)); 400 } 401 402 /** 403 * Draws the elevation profile 404 * 405 * @param g 406 */ 407 private void drawProfile(Graphics g) { 408 IElevationProfile profile = model.getCurrentProfile(); 409 410 int n = Math.min(plotArea.width, profile.getNumberOfWayPoints()); 411 412 if (n == 0) return; // nothing to draw 413 step = profile.getNumberOfWayPoints() / n; 414 415 // int y0 = plotArea.y + 1; 416 int yBottom = getPlotBottom(); 417 Color oldC = g.getColor(); 418 419 for (int i = 0, ip = 0; i < n; i++, ip += step) { 420 WayPoint wpt = profile.getWayPoints().get(ip); 421 int eleVal = (int) ElevationHelper.getElevation(wpt); 422 Color c = renderer.getColorForWaypoint(profile, wpt, 423 ElevationWayPointKind.Plain); 424 425 if (i == this.selectedIndex) { 426 g.setColor(Color.BLACK); 427 drawAlignedString(ElevationHelper.getElevationText(eleVal), 428 (getPlotRight() + getPlotLeft()) / 2, 429 getPlotBottom() + 6, 430 TextAlignment.Centered, 431 g); 432 433 c = renderer.getColorForWaypoint(profile, wpt, ElevationWayPointKind.Highlighted); 434 } 435 int yEle = getYForEelevation(eleVal); 436 int x = getPlotLeft() + i; 437 438 g.setColor(c); 439 g.drawLine(x, yBottom, x, yEle); 440 g.setColor(ElevationColors.EPLightBlue); 441 } 442 g.setColor(oldC); 443 } 444 445 446 /* (non-Javadoc) 447 * @see javax.swing.JComponent#paintBorder(java.awt.Graphics) 448 */ 449 @Override 450 protected void paintBorder(Graphics g) { 451 super.paintBorder(g); 452 453 Border loweredbevel = BorderFactory.createLoweredBevelBorder(); 454 this.setBorder(loweredbevel); 455 } 456 457 458 /** 459 * Determines the size of the plot area depending on the panel size. 460 */ 461 private void createOrUpdatePlotArea() { 462 Dimension caSize = getSize(); 463 464 if (plotArea == null) { 465 plotArea = new Rectangle(0, 0, caSize.width, caSize.height); 466 } else { 467 plotArea.width = caSize.width; 468 plotArea.height = caSize.height; 469 } 470 471 plotArea.setLocation(0, 0); 472 plotArea.grow(-10, -15); 473 } 474 475 /* 476 * (non-Javadoc) 477 * 478 * @seejava.awt.event.ComponentListener#componentHidden(java.awt.event. 479 * ComponentEvent) 480 */ 481 public void componentHidden(ComponentEvent arg0) { 482 // TODO Auto-generated method stub 483 } 484 485 /* 486 * (non-Javadoc) 487 * 488 * @see 489 * java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent 490 * ) 491 */ 492 public void componentMoved(ComponentEvent arg0) { 493 // TODO Auto-generated method stub 494 } 495 496 /* 497 * (non-Javadoc) 498 * 499 * @seejava.awt.event.ComponentListener#componentResized(java.awt.event. 500 * ComponentEvent) 501 */ 502 public void componentResized(ComponentEvent arg0) { 503 createOrUpdatePlotArea(); 504 } 505 506 /* 507 * (non-Javadoc) 508 * 509 * @see 510 * java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent 511 * ) 512 */ 513 public void componentShown(ComponentEvent arg0) { 514 // TODO Auto-generated method stub 515 516 } 517 518 @Override 519 public void mouseDragged(MouseEvent arg0) { 520 // TODO Auto-generated method stub 521 522 } 523 524 @Override 525 public void mouseMoved(MouseEvent arg0) { 526 if (isPainting || arg0.isControlDown() || arg0.isAltDown() || arg0.isShiftDown()) arg0.consume(); 527 528 int x = arg0.getX(); 529 int l = this.getX(); 530 int pl = this.getPlotLeft(); 531 int newIdx = x - l - pl; 532 533 if (newIdx != this.selectedIndex && newIdx >= 0) { 534 this.selectedIndex = newIdx; 535 this.repaint(); 536 fireSelectionChanged(getSelectedWayPoint()); 537 } 538 } 539 540 @Override 541 public String getToolTipText() { 542 WayPoint wpt = getSelectedWayPoint(); 543 if (wpt != null) { 544 return String.format("%s: %s", ElevationHelper.getTimeText(wpt), ElevationHelper.getElevationText(wpt)); 545 } 546 547 return super.getToolTipText(); 548 } 267 /** 268 * Formats the date in a predefined manner: "21. Oct 2010, 12:10". 269 * @param date 270 * @return 271 */ 272 private String formatDate(Date date) { 273 Format formatter = new SimpleDateFormat("d MMM yy, HH:mm"); 274 275 return formatter.format(date); 276 } 277 278 /** 279 * Helper function to draw elevation axes. 280 * @param g 281 */ 282 private void drawElevationLines(Graphics g) { 283 IElevationProfile profile = model.getCurrentProfile(); 284 285 double diff = profile.getHeightDifference(); 286 287 if (diff == 0.0) { 288 return; 289 } 290 291 double z10 = Math.floor(Math.log10(diff)); 292 double scaleUnit = Math.pow(10, z10); // scale unit, e. g. 100 for 293 // values below 1000 294 295 int upperLimit = (int) (Math.round(Math.ceil(profile.getMaxHeight() 296 / scaleUnit)) * scaleUnit); 297 int lowerLimit = (int) (Math.round(Math.floor(profile.getMinHeight() 298 / scaleUnit)) * scaleUnit); 299 int su = (int) scaleUnit; 300 301 for (int i = lowerLimit; i <= upperLimit; i += su) { 302 int yLine = getYForEelevation(i); 303 304 // check bounds 305 if (yLine <= getPlotBottom() && yLine >= getPlotTop()) { 306 String txt = ElevationHelper.getElevationText(i); 307 308 Rectangle r = drawAlignedString(txt, getPlotHCenter(), yLine - 2, 309 TextAlignment.Right, g); 310 r.grow(2, 2); 311 312 // Draw left and right line segment 313 g.drawLine(getPlotLeftAxis(), yLine, r.x, 314 yLine); 315 g.drawLine(r.x + r.width, yLine, getPlotRight(), 316 yLine); 317 // Draw label with shadow 318 g.setColor(Color.WHITE); 319 drawAlignedString(txt, getPlotHCenter() + 1, yLine - 1, 320 TextAlignment.Right, g); 321 g.setColor(Color.BLACK); 322 drawAlignedString(txt, getPlotHCenter(), yLine - 2, 323 TextAlignment.Right, g); 324 } 325 } 326 } 327 328 /** 329 * Gets the x value of the left border for axes (slightly smaller than the 330 * left x). 331 * 332 * @return 333 */ 334 private int getPlotLeftAxis() { 335 return plotArea.x - 3; 336 } 337 338 /** 339 * Gets the x value of the left border. 340 * 341 * @return 342 */ 343 private int getPlotLeft() { 344 return plotArea.x + 1; 345 } 346 347 /** 348 * Gets the horizontal center coordinate (mid between left and right x). 349 * 350 * @return 351 */ 352 private int getPlotHCenter() { 353 return (getPlotLeft() + getPlotRight()) / 2; 354 } 355 356 /** 357 * Gets the vertical center coordinate (mid between top and bottom y). 358 * 359 * @return 360 */ 361 private int getPlotVCenter() { 362 return (getPlotTop() + getPlotBottom()) / 2; 363 } 364 365 /** 366 * Gets the x value of the right border. 367 * 368 * @return 369 */ 370 private int getPlotRight() { 371 return plotArea.x + plotArea.width - 1; 372 } 373 374 private int getPlotBottom() { 375 return plotArea.y + plotArea.height - 1; 376 } 377 378 private int getPlotTop() { 379 return plotArea.y + 1; 380 } 381 382 /** 383 * Gets for an elevation value the according y coordinate in the plot area. 384 * 385 * @param elevation 386 * @return The y coordinate in the plot area. 387 */ 388 private int getYForEelevation(int elevation) { 389 int y1 = getPlotBottom(); 390 391 IElevationProfile profile = model.getCurrentProfile(); 392 393 if (!profile.hasElevationData()) { 394 return y1; 395 } 396 397 double diff = profile.getHeightDifference(); 398 399 return y1 - (int) Math.round(((elevation - profile.getMinHeight()) / diff * plotArea.height)); 400 } 401 402 /** 403 * Draws the elevation profile 404 * 405 * @param g 406 */ 407 private void drawProfile(Graphics g) { 408 IElevationProfile profile = model.getCurrentProfile(); 409 410 int nwp = profile.getNumberOfWayPoints(); 411 int n = Math.min(plotArea.width, nwp); 412 413 if (n == 0) return; // nothing to draw 414 // compute step size in panel (add 1 to make sure that 415 // the complete range fits into panel 416 step = (nwp / n) + 1; 417 418 int yBottom = getPlotBottom(); 419 Color oldC = g.getColor(); 420 421 for (int i = 0, ip = 0; i < n && ip < nwp; i++, ip += step) { 422 WayPoint wpt = profile.getWayPoints().get(ip); 423 int eleVal = (int) ElevationHelper.getElevation(wpt); 424 Color c = renderer.getColorForWaypoint(profile, wpt, 425 ElevationWayPointKind.Plain); 426 427 if (i == this.selectedIndex) { 428 g.setColor(Color.BLACK); 429 drawAlignedString(ElevationHelper.getElevationText(eleVal), 430 (getPlotRight() + getPlotLeft()) / 2, 431 getPlotBottom() + 6, 432 TextAlignment.Centered, 433 g); 434 435 c = renderer.getColorForWaypoint(profile, wpt, ElevationWayPointKind.Highlighted); 436 } 437 int yEle = getYForEelevation(eleVal); 438 int x = getPlotLeft() + i; 439 440 g.setColor(c); 441 g.drawLine(x, yBottom, x, yEle); 442 g.setColor(ElevationColors.EPLightBlue); 443 } 444 g.setColor(oldC); 445 } 446 447 448 /* (non-Javadoc) 449 * @see javax.swing.JComponent#paintBorder(java.awt.Graphics) 450 */ 451 @Override 452 protected void paintBorder(Graphics g) { 453 super.paintBorder(g); 454 455 Border loweredbevel = BorderFactory.createLoweredBevelBorder(); 456 this.setBorder(loweredbevel); 457 } 458 459 460 /** 461 * Determines the size of the plot area depending on the panel size. 462 */ 463 private void createOrUpdatePlotArea() { 464 Dimension caSize = getSize(); 465 466 if (plotArea == null) { 467 plotArea = new Rectangle(0, 0, caSize.width, caSize.height); 468 } else { 469 plotArea.width = caSize.width; 470 plotArea.height = caSize.height; 471 } 472 473 plotArea.setLocation(0, 0); 474 plotArea.grow(-10, -15); 475 } 476 477 /* 478 * (non-Javadoc) 479 * 480 * @seejava.awt.event.ComponentListener#componentHidden(java.awt.event. 481 * ComponentEvent) 482 */ 483 @Override 484 public void componentHidden(ComponentEvent arg0) { 485 // TODO Auto-generated method stub 486 } 487 488 /* 489 * (non-Javadoc) 490 * 491 * @see 492 * java.awt.event.ComponentListener#componentMoved(java.awt.event.ComponentEvent 493 * ) 494 */ 495 @Override 496 public void componentMoved(ComponentEvent arg0) { 497 // TODO Auto-generated method stub 498 } 499 500 /* 501 * (non-Javadoc) 502 * 503 * @seejava.awt.event.ComponentListener#componentResized(java.awt.event. 504 * ComponentEvent) 505 */ 506 @Override 507 public void componentResized(ComponentEvent arg0) { 508 createOrUpdatePlotArea(); 509 } 510 511 /* 512 * (non-Javadoc) 513 * 514 * @see 515 * java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent 516 * ) 517 */ 518 @Override 519 public void componentShown(ComponentEvent arg0) { 520 // TODO Auto-generated method stub 521 522 } 523 524 @Override 525 public void mouseDragged(MouseEvent arg0) { 526 // TODO Auto-generated method stub 527 528 } 529 530 @Override 531 public void mouseMoved(MouseEvent arg0) { 532 if (isPainting || arg0.isControlDown() || arg0.isAltDown() || arg0.isShiftDown()) arg0.consume(); 533 534 int x = arg0.getX(); 535 int l = this.getX(); 536 int pl = this.getPlotLeft(); 537 int newIdx = x - l - pl; 538 539 if (newIdx != this.selectedIndex && newIdx >= 0) { 540 this.selectedIndex = newIdx; 541 this.repaint(); 542 fireSelectionChanged(getSelectedWayPoint()); 543 } 544 } 545 546 @Override 547 public String getToolTipText() { 548 WayPoint wpt = getSelectedWayPoint(); 549 if (wpt != null) { 550 return String.format("%s: %s", ElevationHelper.getTimeText(wpt), ElevationHelper.getElevationText(wpt)); 551 } 552 553 return super.getToolTipText(); 554 } 549 555 }
Note:
See TracChangeset
for help on using the changeset viewer.