Ignore:
Timestamp:
2013-09-27T20:35:14+02:00 (11 years ago)
Author:
oliverw
Message:

[josm_elevationprofile] Bugfix: Panel did not show complete track in some cases

File:
1 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/ElevationProfile/src/org/openstreetmap/josm/plugins/elevation/gui/ElevationProfilePanel.java

    r29976 r29981  
    11/**
    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.
    66 *
    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.
    1010 *
    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.
    1212 * If not, see <http://www.gnu.org/licenses/>.
    1313 */
     
    4848 */
    4949public 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);
    95218                }
    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
    263263        private void drawHCenteredString(String s, int x, int y, Graphics g) {
    264264                drawAlignedString(s, x, y, TextAlignment.Centered, g);
    265265        }*/
    266266
    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    }
    549555}
Note: See TracChangeset for help on using the changeset viewer.