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; } }