现在的位置: 首页 > 综合 > 正文

java 画带箭头的直线

2018年01月30日 ⁄ 综合 ⁄ 共 2775字 ⁄ 字号 评论关闭

      最近需要用到java带箭头的直线,在网上搜了一下,这里主要是来自网上,自己添加了箭头随鼠标的移动而改变的功能。自己还一直没有理解是怎么计算箭头的坐标的。看来高中学的几何知识都搞忘咯。不说这些了,先来看一看运行的效果。

具体代码如下:

package com.mengke.j2se.scpture;

import java.awt.*;
import javax.swing.*;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.*;

class ArrowLinePanel extends JPanel implements MouseMotionListener,MouseListener{
	// confirm the line position
  private int x1 = 0;
  private int y1 = 0;
  private int x2 = 0;
  private int y2 = 0;
  
	public ArrowLinePanel() {
		setBackground(Color.white);
		addMouseListener(this);
		addMouseMotionListener(this);
	}

	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2 = (Graphics2D) g;
		g2.setPaint(Color.black);
		drawAL(x1, y1, x2, y2, g2);// 这里x1, y1, x2, y2必须要声明并且初始化,而具体声明的位置和初始化的值
	}

	public static void drawAL(int sx, int sy, int ex, int ey, Graphics2D g2)
	{

		double H = 10; // 箭头高度
		double L = 4; // 底边的一半
		int x3 = 0;
		int y3 = 0;
		int x4 = 0;
		int y4 = 0;
		double awrad = Math.atan(L / H); // 箭头角度
		double arraow_len = Math.sqrt(L * L + H * H); // 箭头的长度
		double[] arrXY_1 = rotateVec(ex - sx, ey - sy, awrad, true, arraow_len);
		double[] arrXY_2 = rotateVec(ex - sx, ey - sy, -awrad, true, arraow_len);
		double x_3 = ex - arrXY_1[0]; // (x3,y3)是第一端点
		double y_3 = ey - arrXY_1[1];
		double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
		double y_4 = ey - arrXY_2[1];

		Double X3 = new Double(x_3);
		x3 = X3.intValue();
		Double Y3 = new Double(y_3);
		y3 = Y3.intValue();
		Double X4 = new Double(x_4);
		x4 = X4.intValue();
		Double Y4 = new Double(y_4);
		y4 = Y4.intValue();
		// 画线
		g2.drawLine(sx, sy, ex, ey);
		//
		GeneralPath triangle = new GeneralPath();
		triangle.moveTo(ex, ey);
		triangle.lineTo(x3, y3);
		triangle.lineTo(x4, y4);
		triangle.closePath();
		//实心箭头
		g2.fill(triangle);
		//非实心箭头
		//g2.draw(triangle);

	}

	// 计算
	public static double[] rotateVec(int px, int py, double ang,
			boolean isChLen, double newLen) {

		double mathstr[] = new double[2];
		// 矢量旋转函数,参数含义分别是x分量、y分量、旋转角、是否改变长度、新长度
		double vx = px * Math.cos(ang) - py * Math.sin(ang);
		double vy = px * Math.sin(ang) + py * Math.cos(ang);
		if (isChLen) {
			double d = Math.sqrt(vx * vx + vy * vy);
			vx = vx / d * newLen;
			vy = vy / d * newLen;
			mathstr[0] = vx;
			mathstr[1] = vy;
		}
		return mathstr;
	}

	@Override
	public void mouseDragged(MouseEvent e) {
                 //改变箭头的坐标
		x2 = e.getX();
		y2 = e.getY();
		repaint();
	}

	@Override
	public void mouseMoved(MouseEvent e) {
	}

	@Override
	public void mouseClicked(MouseEvent e) {
	}

	@Override
	public void mouseEntered(MouseEvent e) {
	}

	@Override
	public void mouseExited(MouseEvent e) {
	}

	@Override
	public void mousePressed(MouseEvent e) {
                //设置箭头的起始坐标
		x1 = e.getX();
		y1 = e.getY();
	}

	@Override
	public void mouseReleased(MouseEvent e) {
		
	}

}

 

测试类:

package com.mengke.j2se.scpture;

public class DrawFrame extends JFrame {
	// 活动图窗口大小
	public static final int DEFAULT_WIDTH = 1000;
	public static final int DEFAULT_HEIGHT = 800;
	public DrawFrame() {
		setTitle("Activity Diagram");
		setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
		ArrowLinePanel panel = new ArrowLinePanel();
		add(panel);
	}
	
	public static void main(String args[]) {
		DrawFrame frame = new DrawFrame();
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frame.setVisible(true);
	}
	
}

 

抱歉!评论已关闭.