Program: 76092
Project: 76092
Buggy source:
/** 
 * Draw the axes using the current range, label, and title information. If the second argument is true, clear the display before redrawing. This method is called by paintComponent().  To cause it to be called you would normally call repaint(), which eventually causes paintComponent() to be called. <p> Note that this is synchronized so that points are not added by other threads while the drawing is occurring.  This method should be called only from the event dispatch thread, consistent with swing policy.
 * @param graphics The graphics context.
 * @param clearfirst If true, clear the plot before proceeding.
 */
protected synchronized void _drawPlot(Graphics graphics,boolean clearfirst){
  if (graphics == null)   return;
  Rectangle drawRect=getBounds();
  graphics.setPaintMode();
  if (_errorMsg != null) {
    int fheight=_labelFontMetrics.getHeight() + 2;
    int msgy=fheight;
    graphics.setColor(Color.black);
    for (int i=0; i < _errorMsg.length; i++) {
      graphics.drawString(_errorMsg[i],10,msgy);
      msgy+=fheight;
      System.err.println(_errorMsg[i]);
    }
    return;
  }
  if (!_xRangeGiven) {
    if (_xBottom > _xTop) {
      _setXRange(0,0);
    }
 else {
      _setXRange(_xBottom,_xTop);
    }
  }
  if (!_yRangeGiven) {
    if (_yBottom > _yTop) {
      _setYRange(0,0);
    }
 else {
      _setYRange(_yBottom,_yTop);
    }
  }
  int titley=0;
  int titlefontheight=_titleFontMetrics.getHeight();
  if (_title == null) {
    _title="String_Node_Str";
  }
  if (_title != null || _yExp != 0) {
    titley=titlefontheight + _topPadding;
  }
  graphics.setFont(_labelFont);
  int labelheight=_labelFontMetrics.getHeight();
  int halflabelheight=labelheight / 2;
  int ySPos=drawRect.height - 5;
  int xSPos=drawRect.width - _rightPadding;
  if (_xlog)   _xExp=(int)Math.floor(_xtickMin);
  if (_xExp != 0 && _xticks == null) {
    String superscript=Integer.toString(_xExp);
    xSPos-=_superscriptFontMetrics.stringWidth(superscript);
    graphics.setFont(_superscriptFont);
    if (!_xlog) {
      graphics.drawString(superscript,xSPos,ySPos - halflabelheight);
      xSPos-=_labelFontMetrics.stringWidth("String_Node_Str");
      graphics.setFont(_labelFont);
      graphics.drawString("String_Node_Str",xSPos,ySPos);
    }
    _bottomPadding=(3 * labelheight) / 2 + 5;
  }
  if (_xlabel != null && _bottomPadding < labelheight + 5) {
    _bottomPadding=labelheight + 5;
  }
  _uly=titley + 5;
  _lry=drawRect.height - labelheight - _bottomPadding- 3;
  int height=_lry - _uly;
  _yscale=height / (_yMax - _yMin);
  _ytickscale=height / (_ytickMax - _ytickMin);
  int ny=2 + height / (labelheight + 10);
  double yStep=_roundUp((_ytickMax - _ytickMin) / (double)ny);
  double yStart=yStep * Math.ceil(_ytickMin / yStep);
  int widesty=0;
  String ylabels[]=new String[ny];
  int ylabwidth[]=new int[ny];
  int ind=0;
  if (_yticks == null) {
    Vector ygrid=null;
    if (_ylog) {
      ygrid=_gridInit(yStart,yStep,true,null);
    }
    int numfracdigits=_numFracDigits(yStep);
    double yTmpStart=yStart;
    if (_ylog)     yTmpStart=_gridStep(ygrid,yStart,yStep,_ylog);
    for (double ypos=yTmpStart; ypos <= _ytickMax; ypos=_gridStep(ygrid,ypos,yStep,_ylog)) {
      if (ind >= ny)       break;
      String yticklabel;
      if (_ylog) {
        yticklabel=_formatLogNum(ypos,numfracdigits);
      }
 else {
        yticklabel=_formatNum(ypos,numfracdigits);
      }
      ylabels[ind]=yticklabel;
      int lw=_labelFontMetrics.stringWidth(yticklabel);
      ylabwidth[ind++]=lw;
      if (lw > widesty) {
        widesty=lw;
      }
    }
  }
 else {
    Enumeration nl=_yticklabels.elements();
    while (nl.hasMoreElements()) {
      String label=(String)nl.nextElement();
      int lw=_labelFontMetrics.stringWidth(label);
      if (lw > widesty) {
        widesty=lw;
      }
    }
  }
  if (_ylabel != null) {
    _ulx=widesty + _labelFontMetrics.stringWidth("String_Node_Str") + _leftPadding;
  }
 else {
    _ulx=widesty + _leftPadding;
  }
  int legendwidth=_drawLegend(graphics,drawRect.width - _rightPadding,_uly);
  _lrx=drawRect.width - legendwidth - _rightPadding;
  int width=_lrx - _ulx;
  _xscale=width / (_xMax - _xMin);
  _xtickscale=width / (_xtickMax - _xtickMin);
  graphics.setColor(Color.white);
  graphics.fillRect(_ulx,_uly,width,height);
  graphics.setColor(_foreground);
  graphics.drawRect(_ulx,_uly,width,height);
  int tickLength=5;
  int xCoord1=_ulx + tickLength;
  int xCoord2=_lrx - tickLength;
  if (_yticks == null) {
    Vector ygrid=null;
    double yTmpStart=yStart;
    if (_ylog) {
      ygrid=_gridInit(yStart,yStep,true,null);
      yTmpStart=_gridStep(ygrid,yStart,yStep,_ylog);
      ny=ind;
    }
    ind=0;
    boolean needExponent=_ylog;
    for (double ypos=yTmpStart; ypos <= _ytickMax; ypos=_gridStep(ygrid,ypos,yStep,_ylog)) {
      if (ind >= ny)       break;
      int yCoord1=_lry - (int)((ypos - _ytickMin) * _ytickscale);
      int offset=0;
      if (ind > 0 && !_ylog)       offset=halflabelheight;
      graphics.drawLine(_ulx,yCoord1,xCoord1,yCoord1);
      graphics.drawLine(_lrx,yCoord1,xCoord2,yCoord1);
      if (_grid && yCoord1 != _uly && yCoord1 != _lry) {
        graphics.setColor(Color.lightGray);
        graphics.drawLine(xCoord1,yCoord1,xCoord2,yCoord1);
        graphics.setColor(_foreground);
      }
      if (_ylog && ylabels[ind].indexOf('e') != -1)       needExponent=false;
      graphics.drawString(ylabels[ind],_ulx - ylabwidth[ind++] - 4,yCoord1 + offset);
    }
    if (_ylog) {
      Vector unlabeledgrid=_gridInit(yStart,yStep,false,ygrid);
      if (unlabeledgrid.size() > 0) {
        double tmpStep=(yStep > 1.0) ? 1.0 : yStep;
        for (double ypos=_gridStep(unlabeledgrid,yStart,tmpStep,_ylog); ypos <= _ytickMax; ypos=_gridStep(unlabeledgrid,ypos,tmpStep,_ylog)) {
          int yCoord1=_lry - (int)((ypos - _ytickMin) * _ytickscale);
          if (_grid && yCoord1 != _uly && yCoord1 != _lry) {
            graphics.setColor(Color.lightGray);
            graphics.drawLine(_ulx + 1,yCoord1,_lrx - 1,yCoord1);
            graphics.setColor(_foreground);
          }
        }
      }
      if (needExponent) {
        _yExp=(int)Math.floor(yTmpStart);
      }
 else {
        _yExp=0;
      }
    }
    if (_yExp != 0) {
      graphics.drawString("String_Node_Str",2,titley);
      graphics.setFont(_superscriptFont);
      graphics.drawString(Integer.toString(_yExp),_labelFontMetrics.stringWidth("String_Node_Str") + 2,titley - halflabelheight);
      graphics.setFont(_labelFont);
    }
  }
 else {
    Enumeration nt=_yticks.elements();
    Enumeration nl=_yticklabels.elements();
    while (nl.hasMoreElements()) {
      String label=(String)nl.nextElement();
      double ypos=((Double)(nt.nextElement())).doubleValue();
      if (ypos > _yMax || ypos < _yMin)       continue;
      int yCoord1=_lry - (int)((ypos - _yMin) * _yscale);
      int offset=0;
      if (ypos < _lry - labelheight)       offset=halflabelheight;
      graphics.drawLine(_ulx,yCoord1,xCoord1,yCoord1);
      graphics.drawLine(_lrx,yCoord1,xCoord2,yCoord1);
      if (_grid && yCoord1 != _uly && yCoord1 != _lry) {
        graphics.setColor(Color.lightGray);
        graphics.drawLine(xCoord1,yCoord1,xCoord2,yCoord1);
        graphics.setColor(_foreground);
      }
      graphics.drawString(label,_ulx - _labelFontMetrics.stringWidth(label) - 3,yCoord1 + offset);
    }
  }
  int yCoord1=_uly + tickLength;
  int yCoord2=_lry - tickLength;
  if (_xticks == null) {
    int nx=10;
    double xStep=0.0;
    int numfracdigits=0;
    int charwidth=_labelFontMetrics.stringWidth("String_Node_Str");
    if (_xlog) {
      nx=2 + width / ((charwidth * 6) + 10);
    }
 else {
      int count=0;
      while (count++ <= 10) {
        xStep=_roundUp((_xtickMax - _xtickMin) / (double)nx);
        numfracdigits=_numFracDigits(xStep);
        int intdigits=_numIntDigits(_xtickMax);
        int inttemp=_numIntDigits(_xtickMin);
        if (intdigits < inttemp) {
          intdigits=inttemp;
        }
        int maxlabelwidth=charwidth * (numfracdigits + 2 + intdigits);
        int savenx=nx;
        nx=2 + width / (maxlabelwidth + 10);
        if (nx - savenx <= 1 || savenx - nx <= 1)         break;
      }
    }
    xStep=_roundUp((_xtickMax - _xtickMin) / (double)nx);
    numfracdigits=_numFracDigits(xStep);
    double xStart=xStep * Math.ceil(_xtickMin / xStep);
    Vector xgrid=null;
    double xTmpStart=xStart;
    if (_xlog) {
      xgrid=_gridInit(xStart,xStep,true,null);
      xTmpStart=_gridRoundUp(xgrid,xStart);
    }
    boolean needExponent=_xlog;
    for (double xpos=xTmpStart; xpos <= _xtickMax; xpos=_gridStep(xgrid,xpos,xStep,_xlog)) {
      String xticklabel;
      if (_xlog) {
        xticklabel=_formatLogNum(xpos,numfracdigits);
        if (xticklabel.indexOf('e') != -1)         needExponent=false;
      }
 else {
        xticklabel=_formatNum(xpos,numfracdigits);
      }
      xCoord1=_ulx + (int)((xpos - _xtickMin) * _xtickscale);
      graphics.drawLine(xCoord1,_uly,xCoord1,yCoord1);
      graphics.drawLine(xCoord1,_lry,xCoord1,yCoord2);
      if (_grid && xCoord1 != _ulx && xCoord1 != _lrx) {
        graphics.setColor(Color.lightGray);
        graphics.drawLine(xCoord1,yCoord1,xCoord1,yCoord2);
        graphics.setColor(_foreground);
      }
      int labxpos=xCoord1 - _labelFontMetrics.stringWidth(xticklabel) / 2;
      graphics.drawString(xticklabel,labxpos,_lry + 3 + labelheight);
    }
    if (_xlog) {
      double tmpStep=(xStep > 1.0) ? 1.0 : xStep;
      xTmpStart=tmpStep * Math.ceil(_xtickMin / tmpStep);
      Vector unlabeledgrid=_gridInit(xTmpStart,tmpStep,false,xgrid);
      if (unlabeledgrid.size() > 0) {
        for (double xpos=_gridStep(unlabeledgrid,xTmpStart,tmpStep,_xlog); xpos <= _xtickMax; xpos=_gridStep(unlabeledgrid,xpos,tmpStep,_xlog)) {
          xCoord1=_ulx + (int)((xpos - _xtickMin) * _xtickscale);
          if (_grid && xCoord1 != _ulx && xCoord1 != _lrx) {
            graphics.setColor(Color.lightGray);
            graphics.drawLine(xCoord1,_uly + 1,xCoord1,_lry - 1);
            graphics.setColor(_foreground);
          }
        }
      }
      if (needExponent) {
        _xExp=(int)Math.floor(xTmpStart);
        graphics.setFont(_superscriptFont);
        graphics.drawString(Integer.toString(_xExp),xSPos,ySPos - halflabelheight);
        xSPos-=_labelFontMetrics.stringWidth("String_Node_Str");
        graphics.setFont(_labelFont);
        graphics.drawString("String_Node_Str",xSPos,ySPos);
      }
 else {
        _xExp=0;
      }
    }
  }
 else {
    Enumeration nt=_xticks.elements();
    Enumeration nl=_xticklabels.elements();
    double preLength=0.0;
    while (nl.hasMoreElements()) {
      String label=(String)nl.nextElement();
      double xpos=((Double)(nt.nextElement())).doubleValue();
      if (xpos > _xMax || xpos < _xMin)       continue;
      xCoord1=_ulx + (int)((xpos - _xMin) * _xscale);
      int labxpos=xCoord1 - _labelFontMetrics.stringWidth(label) / 2;
      if (labxpos > preLength) {
        preLength=xCoord1 + _labelFontMetrics.stringWidth(label) / 2 + 10;
        graphics.drawString(label,labxpos,_lry + 3 + labelheight);
        graphics.drawLine(xCoord1,_uly,xCoord1,yCoord1);
        graphics.drawLine(xCoord1,_lry,xCoord1,yCoord2);
        if (_grid && xCoord1 != _ulx && xCoord1 != _lrx) {
          graphics.setColor(Color.lightGray);
          graphics.drawLine(xCoord1,yCoord1,xCoord1,yCoord2);
          graphics.setColor(_foreground);
        }
      }
    }
  }
  graphics.setColor(_foreground);
  if (_title != null) {
    graphics.setFont(_titleFont);
    int titlex=_ulx + (width - _titleFontMetrics.stringWidth(_title)) / 2;
    graphics.drawString(_title,titlex,titley);
  }
  graphics.setFont(_labelFont);
  if (_xlabel != null) {
    int labelx=_ulx + (width - _labelFontMetrics.stringWidth(_xlabel)) / 2;
    graphics.drawString(_xlabel,labelx,ySPos);
  }
  int charcenter=2 + _labelFontMetrics.stringWidth("String_Node_Str") / 2;
  int charheight=labelheight;
  if (_ylabel != null) {
    int yl=_ylabel.length();
    int starty=_uly + (_lry - _uly) / 2 - yl * charheight / 2 + charheight;
    for (int i=0; i < yl; i++) {
      String nchar=_ylabel.substring(i,i + 1);
      int cwidth=_labelFontMetrics.stringWidth(nchar);
      graphics.drawString(nchar,charcenter - cwidth / 2,starty);
      starty+=charheight;
    }
  }
}

Fixed version (ground truth):
/** 
 * Draw the axes using the current range, label, and title information. If the second argument is true, clear the display before redrawing. This method is called by paintComponent().  To cause it to be called you would normally call repaint(), which eventually causes paintComponent() to be called. <p> Note that this is synchronized so that points are not added by other threads while the drawing is occurring.  This method should be called only from the event dispatch thread, consistent with swing policy.
 * @param graphics The graphics context.
 * @param clearfirst If true, clear the plot before proceeding.
 */
protected synchronized void _drawPlot(Graphics graphics,boolean clearfirst){
  if (graphics == null)   return;
  Rectangle drawRect=getBounds();
  graphics.setPaintMode();
  if (_errorMsg != null) {
    int fheight=_labelFontMetrics.getHeight() + 2;
    int msgy=fheight;
    graphics.setColor(Color.black);
    for (int i=0; i < _errorMsg.length; i++) {
      graphics.drawString(_errorMsg[i],10,msgy);
      msgy+=fheight;
      System.err.println(_errorMsg[i]);
    }
    return;
  }
  if (!_xRangeGiven) {
    if (_xBottom > _xTop) {
      _setXRange(0,0);
    }
 else {
      _setXRange(_xBottom,_xTop);
    }
  }
  if (!_yRangeGiven) {
    if (_yBottom > _yTop) {
      _setYRange(0,0);
    }
 else {
      _setYRange(_yBottom,_yTop);
    }
  }
  int titley=0;
  int titlefontheight=_titleFontMetrics.getHeight();
  if (_title == null) {
    _title="String_Node_Str";
  }
  if (_title != null || _yExp != 0) {
    titley=titlefontheight + _topPadding;
  }
  Font previousFont=graphics.getFont();
  graphics.setFont(_labelFont);
  int labelheight=_labelFontMetrics.getHeight();
  int halflabelheight=labelheight / 2;
  int ySPos=drawRect.height - 5;
  int xSPos=drawRect.width - _rightPadding;
  if (_xlog)   _xExp=(int)Math.floor(_xtickMin);
  if (_xExp != 0 && _xticks == null) {
    String superscript=Integer.toString(_xExp);
    xSPos-=_superscriptFontMetrics.stringWidth(superscript);
    graphics.setFont(_superscriptFont);
    if (!_xlog) {
      graphics.drawString(superscript,xSPos,ySPos - halflabelheight);
      xSPos-=_labelFontMetrics.stringWidth("String_Node_Str");
      graphics.setFont(_labelFont);
      graphics.drawString("String_Node_Str",xSPos,ySPos);
    }
    _bottomPadding=(3 * labelheight) / 2 + 5;
  }
  if (_xlabel != null && _bottomPadding < labelheight + 5) {
    _bottomPadding=labelheight + 5;
  }
  _uly=titley + 5;
  _lry=drawRect.height - labelheight - _bottomPadding- 3;
  int height=_lry - _uly;
  _yscale=height / (_yMax - _yMin);
  _ytickscale=height / (_ytickMax - _ytickMin);
  int ny=2 + height / (labelheight + 10);
  double yStep=_roundUp((_ytickMax - _ytickMin) / (double)ny);
  double yStart=yStep * Math.ceil(_ytickMin / yStep);
  int widesty=0;
  String ylabels[]=new String[ny];
  int ylabwidth[]=new int[ny];
  int ind=0;
  if (_yticks == null) {
    Vector ygrid=null;
    if (_ylog) {
      ygrid=_gridInit(yStart,yStep,true,null);
    }
    int numfracdigits=_numFracDigits(yStep);
    double yTmpStart=yStart;
    if (_ylog)     yTmpStart=_gridStep(ygrid,yStart,yStep,_ylog);
    for (double ypos=yTmpStart; ypos <= _ytickMax; ypos=_gridStep(ygrid,ypos,yStep,_ylog)) {
      if (ind >= ny)       break;
      String yticklabel;
      if (_ylog) {
        yticklabel=_formatLogNum(ypos,numfracdigits);
      }
 else {
        yticklabel=_formatNum(ypos,numfracdigits);
      }
      ylabels[ind]=yticklabel;
      int lw=_labelFontMetrics.stringWidth(yticklabel);
      ylabwidth[ind++]=lw;
      if (lw > widesty) {
        widesty=lw;
      }
    }
  }
 else {
    Enumeration nl=_yticklabels.elements();
    while (nl.hasMoreElements()) {
      String label=(String)nl.nextElement();
      int lw=_labelFontMetrics.stringWidth(label);
      if (lw > widesty) {
        widesty=lw;
      }
    }
  }
  if (_ylabel != null) {
    _ulx=widesty + _labelFontMetrics.stringWidth("String_Node_Str") + _leftPadding;
  }
 else {
    _ulx=widesty + _leftPadding;
  }
  int legendwidth=_drawLegend(graphics,drawRect.width - _rightPadding,_uly);
  _lrx=drawRect.width - legendwidth - _rightPadding;
  int width=_lrx - _ulx;
  _xscale=width / (_xMax - _xMin);
  _xtickscale=width / (_xtickMax - _xtickMin);
  graphics.setColor(Color.white);
  graphics.fillRect(_ulx,_uly,width,height);
  graphics.setColor(_foreground);
  graphics.drawRect(_ulx,_uly,width,height);
  int tickLength=5;
  int xCoord1=_ulx + tickLength;
  int xCoord2=_lrx - tickLength;
  if (_yticks == null) {
    Vector ygrid=null;
    double yTmpStart=yStart;
    if (_ylog) {
      ygrid=_gridInit(yStart,yStep,true,null);
      yTmpStart=_gridStep(ygrid,yStart,yStep,_ylog);
      ny=ind;
    }
    ind=0;
    boolean needExponent=_ylog;
    for (double ypos=yTmpStart; ypos <= _ytickMax; ypos=_gridStep(ygrid,ypos,yStep,_ylog)) {
      if (ind >= ny)       break;
      int yCoord1=_lry - (int)((ypos - _ytickMin) * _ytickscale);
      int offset=0;
      if (ind > 0 && !_ylog)       offset=halflabelheight;
      graphics.drawLine(_ulx,yCoord1,xCoord1,yCoord1);
      graphics.drawLine(_lrx,yCoord1,xCoord2,yCoord1);
      if (_grid && yCoord1 != _uly && yCoord1 != _lry) {
        graphics.setColor(Color.lightGray);
        graphics.drawLine(xCoord1,yCoord1,xCoord2,yCoord1);
        graphics.setColor(_foreground);
      }
      if (_ylog && ylabels[ind].indexOf('e') != -1)       needExponent=false;
      graphics.drawString(ylabels[ind],_ulx - ylabwidth[ind++] - 4,yCoord1 + offset);
    }
    if (_ylog) {
      Vector unlabeledgrid=_gridInit(yStart,yStep,false,ygrid);
      if (unlabeledgrid.size() > 0) {
        double tmpStep=(yStep > 1.0) ? 1.0 : yStep;
        for (double ypos=_gridStep(unlabeledgrid,yStart,tmpStep,_ylog); ypos <= _ytickMax; ypos=_gridStep(unlabeledgrid,ypos,tmpStep,_ylog)) {
          int yCoord1=_lry - (int)((ypos - _ytickMin) * _ytickscale);
          if (_grid && yCoord1 != _uly && yCoord1 != _lry) {
            graphics.setColor(Color.lightGray);
            graphics.drawLine(_ulx + 1,yCoord1,_lrx - 1,yCoord1);
            graphics.setColor(_foreground);
          }
        }
      }
      if (needExponent) {
        _yExp=(int)Math.floor(yTmpStart);
      }
 else {
        _yExp=0;
      }
    }
    if (_yExp != 0) {
      graphics.drawString("String_Node_Str",2,titley);
      graphics.setFont(_superscriptFont);
      graphics.drawString(Integer.toString(_yExp),_labelFontMetrics.stringWidth("String_Node_Str") + 2,titley - halflabelheight);
      graphics.setFont(_labelFont);
    }
  }
 else {
    Enumeration nt=_yticks.elements();
    Enumeration nl=_yticklabels.elements();
    while (nl.hasMoreElements()) {
      String label=(String)nl.nextElement();
      double ypos=((Double)(nt.nextElement())).doubleValue();
      if (ypos > _yMax || ypos < _yMin)       continue;
      int yCoord1=_lry - (int)((ypos - _yMin) * _yscale);
      int offset=0;
      if (ypos < _lry - labelheight)       offset=halflabelheight;
      graphics.drawLine(_ulx,yCoord1,xCoord1,yCoord1);
      graphics.drawLine(_lrx,yCoord1,xCoord2,yCoord1);
      if (_grid && yCoord1 != _uly && yCoord1 != _lry) {
        graphics.setColor(Color.lightGray);
        graphics.drawLine(xCoord1,yCoord1,xCoord2,yCoord1);
        graphics.setColor(_foreground);
      }
      graphics.drawString(label,_ulx - _labelFontMetrics.stringWidth(label) - 3,yCoord1 + offset);
    }
  }
  int yCoord1=_uly + tickLength;
  int yCoord2=_lry - tickLength;
  if (_xticks == null) {
    int nx=10;
    double xStep=0.0;
    int numfracdigits=0;
    int charwidth=_labelFontMetrics.stringWidth("String_Node_Str");
    if (_xlog) {
      nx=2 + width / ((charwidth * 6) + 10);
    }
 else {
      int count=0;
      while (count++ <= 10) {
        xStep=_roundUp((_xtickMax - _xtickMin) / (double)nx);
        numfracdigits=_numFracDigits(xStep);
        int intdigits=_numIntDigits(_xtickMax);
        int inttemp=_numIntDigits(_xtickMin);
        if (intdigits < inttemp) {
          intdigits=inttemp;
        }
        int maxlabelwidth=charwidth * (numfracdigits + 2 + intdigits);
        int savenx=nx;
        nx=2 + width / (maxlabelwidth + 10);
        if (nx - savenx <= 1 || savenx - nx <= 1)         break;
      }
    }
    xStep=_roundUp((_xtickMax - _xtickMin) / (double)nx);
    numfracdigits=_numFracDigits(xStep);
    double xStart=xStep * Math.ceil(_xtickMin / xStep);
    Vector xgrid=null;
    double xTmpStart=xStart;
    if (_xlog) {
      xgrid=_gridInit(xStart,xStep,true,null);
      xTmpStart=_gridRoundUp(xgrid,xStart);
    }
    boolean needExponent=_xlog;
    for (double xpos=xTmpStart; xpos <= _xtickMax; xpos=_gridStep(xgrid,xpos,xStep,_xlog)) {
      String xticklabel;
      if (_xlog) {
        xticklabel=_formatLogNum(xpos,numfracdigits);
        if (xticklabel.indexOf('e') != -1)         needExponent=false;
      }
 else {
        xticklabel=_formatNum(xpos,numfracdigits);
      }
      xCoord1=_ulx + (int)((xpos - _xtickMin) * _xtickscale);
      graphics.drawLine(xCoord1,_uly,xCoord1,yCoord1);
      graphics.drawLine(xCoord1,_lry,xCoord1,yCoord2);
      if (_grid && xCoord1 != _ulx && xCoord1 != _lrx) {
        graphics.setColor(Color.lightGray);
        graphics.drawLine(xCoord1,yCoord1,xCoord1,yCoord2);
        graphics.setColor(_foreground);
      }
      int labxpos=xCoord1 - _labelFontMetrics.stringWidth(xticklabel) / 2;
      graphics.drawString(xticklabel,labxpos,_lry + 3 + labelheight);
    }
    if (_xlog) {
      double tmpStep=(xStep > 1.0) ? 1.0 : xStep;
      xTmpStart=tmpStep * Math.ceil(_xtickMin / tmpStep);
      Vector unlabeledgrid=_gridInit(xTmpStart,tmpStep,false,xgrid);
      if (unlabeledgrid.size() > 0) {
        for (double xpos=_gridStep(unlabeledgrid,xTmpStart,tmpStep,_xlog); xpos <= _xtickMax; xpos=_gridStep(unlabeledgrid,xpos,tmpStep,_xlog)) {
          xCoord1=_ulx + (int)((xpos - _xtickMin) * _xtickscale);
          if (_grid && xCoord1 != _ulx && xCoord1 != _lrx) {
            graphics.setColor(Color.lightGray);
            graphics.drawLine(xCoord1,_uly + 1,xCoord1,_lry - 1);
            graphics.setColor(_foreground);
          }
        }
      }
      if (needExponent) {
        _xExp=(int)Math.floor(xTmpStart);
        graphics.setFont(_superscriptFont);
        graphics.drawString(Integer.toString(_xExp),xSPos,ySPos - halflabelheight);
        xSPos-=_labelFontMetrics.stringWidth("String_Node_Str");
        graphics.setFont(_labelFont);
        graphics.drawString("String_Node_Str",xSPos,ySPos);
      }
 else {
        _xExp=0;
      }
    }
  }
 else {
    Enumeration nt=_xticks.elements();
    Enumeration nl=_xticklabels.elements();
    double preLength=0.0;
    while (nl.hasMoreElements()) {
      String label=(String)nl.nextElement();
      double xpos=((Double)(nt.nextElement())).doubleValue();
      if (xpos > _xMax || xpos < _xMin)       continue;
      xCoord1=_ulx + (int)((xpos - _xMin) * _xscale);
      int labxpos=xCoord1 - _labelFontMetrics.stringWidth(label) / 2;
      if (labxpos > preLength) {
        preLength=xCoord1 + _labelFontMetrics.stringWidth(label) / 2 + 10;
        graphics.drawString(label,labxpos,_lry + 3 + labelheight);
        graphics.drawLine(xCoord1,_uly,xCoord1,yCoord1);
        graphics.drawLine(xCoord1,_lry,xCoord1,yCoord2);
        if (_grid && xCoord1 != _ulx && xCoord1 != _lrx) {
          graphics.setColor(Color.lightGray);
          graphics.drawLine(xCoord1,yCoord1,xCoord1,yCoord2);
          graphics.setColor(_foreground);
        }
      }
    }
  }
  graphics.setColor(_foreground);
  if (_title != null) {
    graphics.setFont(_titleFont);
    int titlex=_ulx + (width - _titleFontMetrics.stringWidth(_title)) / 2;
    graphics.drawString(_title,titlex,titley);
  }
  graphics.setFont(_labelFont);
  if (_xlabel != null) {
    int labelx=_ulx + (width - _labelFontMetrics.stringWidth(_xlabel)) / 2;
    graphics.drawString(_xlabel,labelx,ySPos);
  }
  int charcenter=2 + _labelFontMetrics.stringWidth("String_Node_Str") / 2;
  int charheight=labelheight;
  if (_ylabel != null) {
    int yl=_ylabel.length();
    int starty=_uly + (_lry - _uly) / 2 - yl * charheight / 2 + charheight;
    for (int i=0; i < yl; i++) {
      String nchar=_ylabel.substring(i,i + 1);
      int cwidth=_labelFontMetrics.stringWidth(nchar);
      graphics.drawString(nchar,charcenter - cwidth / 2,starty);
      starty+=charheight;
    }
  }
  graphics.setFont(previousFont);
}