public void run() {
      while (true) {
        MClusterElement element = (MClusterElement) _mainBuffer.Get();

        // TODO: this is not correct
        // we have to chceck the slideWindowIdx , not the id
        if (_fadeInBuffer == null || _fadeInBuffer.GetClusterIndex() < element.GetClusterIndex()) {

          // System.out.println("do switch");

          setDrawStatus(false);

          _fadeOutBuffer = null;
          _fadeOutBuffer = _fadeInBuffer;
          _fadeInBuffer = new MClusterElementBuffer(element.GetClusterIndex(), _bufferSize);
          _fadeInBuffer.AddElement(element);

          setDrawStatus(true);
        } else if (element.GetClusterIndex() == _fadeInBuffer.GetClusterIndex()) {

          // System.out.println("pure add");
          _fadeInBuffer.AddElement(element);
          setDrawStatus(true);
        }

        // _clusterArea.repaint();
      }
    }
    protected void paintComponent(Graphics g) {

      if (isOpaque()) {
        g.setColor(Color.GRAY);
        g.fillRect(0, 0, getWidth(), getHeight());
      } else {
        g.setColor(COLOR_BACKGROUND);
        g.fillRect(0, 0, getWidth(), getHeight());
      }

      // ********************************************************
      // * Handle the scale issue
      // ********************************************************
      Dimension dim = getSize();

      int height = dim.height - LABEL_HEIGHT;
      int width = dim.width;
      int diameter;
      int tmph = dim.height - LABEL_SENTENCE_HEIGHT;
      int tmpw = LABEL_START_WIDTH;

      g.setFont(FONT_PLAIN);
      if (_fadeInBuffer == null && _fadeOutBuffer == null) {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.GRAY);
        g.drawLine(0, height, width, height);
        g.drawString("Waiting for data...", tmpw, tmph);
        return;
      }

      g.setColor(COLOR_TEXT);
      g.drawLine(0, height, width, height);

      fixMaxMin();
      _pixel_per_unit_y = (double) height / (double) _range_y;
      _pixel_per_unit_x = (double) width / (double) _range_x;

      // ********************************************************
      // * set up the diameter of the point
      // ********************************************************

      diameter = (int) _pixel_per_unit_y;

      if (_pixel_per_unit_x < diameter) diameter = (int) _pixel_per_unit_x;

      if (diameter < POINT_RADIUS) diameter = POINT_RADIUS;

      /**
       * x_cor = ( x + (-1)*_min_x ) * _pixel_per_unit_x x_cor = ( x + neg_min_x ) *
       * _pixel_per_unit_x
       *
       * <p>y_cor = [ (_range_y - (-1)*min_y) - y ] * _pixel_per_unit_y y_cor = [ (sub_y) - y ] *
       * _pixel_per_unit_y
       */
      int neg_min_x = (-1) * _cur_min_x;
      int sub_y = _range_y - ((-1) * _cur_min_y);

      // *****************************************************
      // *	Start to draw (Text)
      // *****************************************************
      g.setFont(FONT_BOLD);
      g.drawString("x :", tmpw, tmph);

      g.setFont(FONT_PLAIN);
      tmpw += LABEL_GAP_WIDTH;
      g.drawString("min = " + _cur_min_x, tmpw, tmph);

      tmpw += LABEL_SEPERATE_WIDTH;
      g.drawString("max = " + _cur_max_x, tmpw, tmph);

      tmpw += LABEL_BETWEEN_WIDTH;
      g.setFont(FONT_BOLD);
      g.drawString("y :", tmpw, tmph);

      g.setFont(FONT_PLAIN);
      tmpw += LABEL_GAP_WIDTH;
      g.drawString("min = " + _cur_min_y, tmpw, tmph);

      tmpw += LABEL_SEPERATE_WIDTH;
      g.drawString("max = " + _cur_max_y, tmpw, tmph);

      // *****************************************************
      // *	Start to draw fadeout
      // *****************************************************
      MClusterElement element = null;
      int x_coor;
      int y_coor;
      int x_draw_coor;
      int y_draw_coor;
      int id;

      int radius = diameter >> 1;
      int ring_x_radius = (int) (_rang_radius * _pixel_per_unit_x);
      int ring_y_radisu = (int) (_rang_radius * _pixel_per_unit_y);
      int ring_x_diameter = ring_x_radius << 1;
      int ring_y_diameter = ring_y_radisu << 1;

      if (_fadeOutBuffer != null && !_fadeOutBuffer.IsAllFadeout()) {

        for (int i = 0; i < _fadeOutBuffer.GetNumOfElements(); i++) {

          element = _fadeOutBuffer.GetElementAt(i);

          id = element.GetClusterId();

          if (id == 0 && !_displayOutliner) continue;

          x_coor = (int) ((double) (element.GetX() + neg_min_x) * _pixel_per_unit_x);
          y_coor = (int) ((double) (sub_y - element.GetY()) * _pixel_per_unit_y);

          if (_rang_radius > 0) {
            x_draw_coor = x_coor - ring_x_radius;
            y_draw_coor = y_coor - ring_y_radisu;

            g.setColor(MColorMgr.GetInstance().GetColor(0, element.GetFadeIdx()));
            g.drawOval(x_draw_coor, y_draw_coor, ring_x_diameter, ring_y_diameter);
          }

          g.setColor(MColorMgr.GetInstance().GetColor(id, element.GetFadeIdx()));

          x_draw_coor = x_coor - radius;
          y_draw_coor = y_coor - radius;

          // System.out.println(element.GetX() + "," + element.GetY());

          g.fillOval(x_draw_coor, y_draw_coor, diameter, diameter);
        }
      }

      // *****************************************************
      // *	Start to draw fadeIn
      // *****************************************************

      if (_fadeInBuffer != null) {

        // System.out.println("print cluter = " + counter++);

        for (int i = 0; i < _fadeInBuffer.GetNumOfElements(); i++) {

          element = _fadeInBuffer.GetElementAt(i);

          id = element.GetClusterId();

          if (id == 0 && !_displayOutliner) continue;

          x_coor = (int) ((double) (element.GetX() + neg_min_x) * _pixel_per_unit_x);
          y_coor = (int) ((double) (sub_y - element.GetY()) * _pixel_per_unit_y);

          if (_rang_radius > 0) {
            x_draw_coor = x_coor - ring_x_radius;
            y_draw_coor = y_coor - ring_y_radisu;

            g.setColor(MColorMgr.GetInstance().GetColor(0, element.GetFadeIdx()));
            g.drawOval(x_draw_coor, y_draw_coor, ring_x_diameter, ring_y_diameter);
          }

          g.setColor(MColorMgr.GetInstance().GetColor(id, element.GetFadeIdx()));
          x_draw_coor = x_coor - radius;
          y_draw_coor = y_coor - radius;

          g.fillOval(x_draw_coor, y_draw_coor, diameter, diameter);
        }
      }

      // *****************************************************
      // *	Start to draw axis
      // *****************************************************
      if (_displayAxis) {

        g.setColor(Color.LIGHT_GRAY);

        if (_cur_min_x < 0 && 0 < _cur_max_x) {
          x_coor = (int) ((double) (neg_min_x) * _pixel_per_unit_x);
          g.drawLine(x_coor, height, x_coor, 0);
        }

        if (_cur_min_y < 0 && 0 < _cur_max_y) {
          y_coor = (int) ((double) (sub_y - 0) * _pixel_per_unit_y);
          g.drawLine(0, y_coor, width, y_coor);
        }
      }
    }