content: package com.alibaba.luaview.debugger.ui;
  
  import java.awt.Color;
  import java.awt.Font;
  import java.awt.Graphics;
  import java.awt.Graphics2D;
  import java.awt.Point;
  import java.awt.RenderingHints;
  import java.awt.event.MouseEvent;
  import java.awt.event.MouseListener;
  import java.awt.event.MouseMotionListener;
  import java.awt.event.MouseWheelEvent;
  import java.awt.event.MouseWheelListener;
  
  import javax.swing.JPanel;
  
  import com.alibaba.luaview.debugger.Config;
  
  abstract public class SrcCodeScrollPanel extends JPanel {
  
  	private static final long serialVersionUID = -8495786914354054078L;
  
  	private Font font = new java.awt.Font("宋体", 0, 14);
  
  	public final int LINE_H = Config.LINE_H;
  
  	private int bar_w = 15;
  
  	private int max_w, max_h;
  
  	private Point point, pointPressed, draggedPoint, m_repressedPoint;
  	private int m_pressedButtonID = -1;
  
  	private final Point zeroPoint = new Point(0, 0);
  
  	public boolean updateUI = true;
  
  	public SrcCodeScrollPanel() {
  		this.setBorder(null);
  		this.addMouseWheelListener(new MouseWheelListener() {
  
  			public void mouseWheelMoved(MouseWheelEvent arg0) {
  				zeroPoint.y += arg0.getWheelRotation() * 50;
  				if (updateUI)
  					updateUI();
  			}
  
  		});
  		this.addMouseMotionListener(new MouseMotionListener() {
  
  			public void mouseDragged(MouseEvent arg0) {
  				if (pointPressed == null) {
  					return;
  				}
  				if (draggedPoint == null) {
  					draggedPoint = arg0.getPoint();
  					return;
  				}
  				if (isOnBarArea(pointPressed.x)) {
  					Point oldPoint = draggedPoint;
  					Point newPoint = arg0.getPoint();
  					draggedPoint = newPoint;
  					scrollBar(newPoint.y - oldPoint.y);
  				} else {
  					Point oldPoint = draggedPoint;
  					Point newPoint = arg0.getPoint();
  					draggedPoint = newPoint;
  					zeroPoint.x -= newPoint.x - oldPoint.x;
  					zeroPoint.y -= newPoint.y - oldPoint.y;
  				}
  				if (updateUI)
  					updateUI();
  			}
  
  			public void mouseMoved(MouseEvent arg0) {
  			}
  
  		});
  		/**
  		 * 鼠标点击
  		 */
  		addMouseListener(new MouseListener() {
  			public void mouseClicked(MouseEvent e) {
  				m_pressedButtonID = e.getButton();
  				if (e.getClickCount() >= 2) {
  					m_repressedPoint = e.getPoint();
  				}
  			}
  
  			public void mouseEntered(MouseEvent e) {
  				int t = e.getButton();
  				if (0 <= t && t <= 2) {
  				} else {
  					draggedPoint = point = pointPressed = null;
  				}
  			}
  
  			public void mouseExited(MouseEvent e) {
  				int t = e.getButton();
  				if (0 <= t && t <= 2) {
  				} else {
  					draggedPoint = point = pointPressed = null;
  				}
  			}
  
  			public void mousePressed(MouseEvent e) {
  				draggedPoint = point = pointPressed = null;
  				pointPressed = e.getPoint();
  
  				Point t = e.getPoint();
  				if (!isOnBarArea(t.x)) {
  					point = t;
  				}
  				requestFocus();
  				updateUI();
  			}
  
  			public void mouseReleased(MouseEvent e) {
  				draggedPoint = point = pointPressed = null;
  			}
  		});
  	}
  
  	private boolean isOnBarArea(int x) {
  		if (screenW - bar_w < x && x < screenW)
  			return true;
  		return false;
  	}
  
  	private void scrollBar(int dy) {
  		zeroPoint.y += dy * max_h / screenH;
  	}
  
  	public void update(Graphics g) {
  		paint(g);
  	}
  
  	private int screenW = 100, screenH = 100;
  
  	public void paint(Graphics tempG) {
  		if (tempG instanceof Graphics2D == false) {
  			return;
  		}
  		Graphics2D g = (Graphics2D) tempG;
  		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
  		g.setFont(font);
  		if (nextY >= 0) {
  			zeroPoint.y = nextY;
  			nextY = -1;
  		}
  		screenW = getWidth();
  		screenH = getHeight();
  		max_w = max_w < screenW ? screenW : max_w;
  		max_h = max_h < screenH ? screenH : max_h;
  		if (zeroPoint.x < 0) {
  			zeroPoint.x = 0;
  		} else if (zeroPoint.x > max_w - screenW) {
  			zeroPoint.x = max_w - screenW;
  		}
  		if (zeroPoint.y < 0) {
  			zeroPoint.y = 0;
  		} else if (zeroPoint.y > max_h - screenH) {
  			zeroPoint.y = max_h - screenH;
  		}
  		g.setColor(Color.white);
  		g.fillRect(0, 0, screenW, screenH);
  		// 显示位置
  		g.setClip(0, 0, screenW - bar_w, screenH);
  		g.translate(-zeroPoint.x, -zeroPoint.y);
  		myPaint(g);// //////////////////////
  		g.translate(zeroPoint.x, zeroPoint.y);
  		// bar
  		int bar_X = screenW - bar_w;
  		int bar_Y = zeroPoint.y * screenH / max_h;
  		int bar_W = bar_w;
  		int bar_H = screenH * screenH / max_h;
  		if (bar_H > screenH - 1) {
  			bar_H = screenH - 1;
  		}
  		g.setClip(0, 0, screenW, screenH);
  		g.setColor(new Color(250, 250, 250));
  		g.fillRect(screenW - bar_w, -1, bar_w + 1, screenH + 2);
  		g.setColor(new Color(232, 232, 232));
  		g.drawRect(screenW - bar_w, -1, bar_w + 8, screenH + 2);
  		fillBar(g, bar_X, bar_Y, bar_W, bar_H);
  
  		if (m_repaint) {
  			m_repaint = false;
  			if (updateUI)
  				updateUI();
  		}
  	}
  
  	private void fillBar(Graphics g, int x, int y, int w, int h) {
  		y += 3;
  		h -= 6;
  		h = h < 2 ? 2 : h;
  		x += 4;
  		w -= 8;
  		g.setColor(new Color(194, 194, 194));
  		g.fillRoundRect(x, y, w, h, w, w);
  		// for (int i = 0; i < w / 2; i++) {
  		// int t = 255 * (i + T) / ((w / 2) + T);
  		// Color c = new Color((t << 16) + (t << 8) + t);
  		// g.setColor(c);
  		// g.drawLine(x + i, y, x + i, y + h);
  		// }
  		// for (int i = w / 2; i < w; i++) {
  		// int t = 255 * ((w - i) + T) / ((w / 2) + T);
  		// Color c = new Color((t << 16) + (t << 8) + t);
  		// g.setColor(c);
  		// g.drawLine(x + i, y, x + i, y + h);
  		// }
  	}
  
  	abstract public void myPaint(Graphics2D g);
  
  	public boolean isRectOnView(int topX, int topY, int endX, int endY) {
  		int viewX0 = zeroPoint.x;
  		int viewY0 = zeroPoint.y;
  		int viewX2 = zeroPoint.x + screenW;
  		int viewY2 = zeroPoint.y + screenH;
  
  		int tempx0 = topX > viewX0 ? topX : viewX0;
  		int tempy0 = topY > viewY0 ? topY : viewY0;
  		int tempx2 = endX > viewX2 ? endX : viewX2;
  		int tempy2 = endY > viewY2 ? endY : viewY2;
  		if (tempx0 < tempx2 && tempy0 < tempy2) {
  			return true;
  		}
  		return false;
  	}
  
  	public boolean isYOnView(int y) {
  		int viewY0 = zeroPoint.y;
  		int viewY2 = zeroPoint.y + screenH;
  		if (y >= viewY0 && y < viewY2) {
  			return true;
  		}
  		return false;
  	}
  
  	private int nextY = -1;
  
  	public void setNextYOnView(int y) {
  		// System.out.println("y:" + y);
  		if (isYOnView(y) == false) {
  			int viewY0 = zeroPoint.y;
  			int viewY2 = zeroPoint.y + screenH;
  			if (Math.abs(viewY0 - y) < Math.abs(viewY2 - y)) {
  				nextY = y - LINE_H;
  			} else {
  				nextY = y - screenH + LINE_H;
  			}
  		} else {
  			nextY = -1;
  		}
  	}
  
  	public void resetMaxWH() {
  		max_w = 10;
  		max_h = 10;
  	}
  
  	public void setMaxW(int w) {
  		max_w = w < max_w ? max_w : w;
  	}
  
  	public int getMaxW() {
  		return max_w;
  	}
  
  	public void setMaxH(int h) {
  		max_h = h < max_h ? max_h : h;
  	}
  
  	public boolean isPressThePoint(int x, int y, int r) {
  		if (point != null) {
  			int tmp = Math.abs(point.x + zeroPoint.x - x) + Math.abs(point.y + zeroPoint.y - y);
  			if (tmp < r) {
  				point = null;
  				return true;
  			}
  		}
  		return false;
  	}
  
  	public boolean isPressTheLine(int x, int y, int h) {
  		if (point != null) {
  			int pY = point.y + zeroPoint.y;
  			int y0 = y - h;
  			int y1 = y;
  			if (y0 < pY && pY < y1) {
  				return true;
  			}
  		}
  		return false;
  	}
  
  	public int pressedPointX() {
  		if (point != null) {
  			return point.x + zeroPoint.x;
  		}
  		return 0;
  	}
  
  	public int pressedPointY() {
  		if (point != null) {
  			return point.y + zeroPoint.y;
  		}
  		return 0;
  	}
  
  	public int pressedButtonID() {
  		return m_pressedButtonID;
  	}
  
  	public void clearPoint() {
  		point = null;
  	}
  
  	private boolean m_repaint;
  
  	public void shouldRepaint() {
  		m_repaint = true;
  	}
  
  	public Point getPressedPoint() {
  		Point t = point;
  		if (t != null) {
  			t.x += zeroPoint.x;
  			t.y += zeroPoint.y;
  		}
  		point = null;
  		return t;
  	}
  
  	public Point getRepressedPoint() {
  		Point t = m_repressedPoint;
  		if (t != null) {
  			t.x += zeroPoint.x;
  			t.y += zeroPoint.y;
  		}
  		m_repressedPoint = null;
  		return t;
  	}
  
  	public void setBarW(int w) {
  		bar_w = w;
  	}
  
  }
  