Java Swing绘制箭头
Java Swing绘制箭头
绘制单向箭头、双向箭头
package com.xiangqian.swing;import javax.swing.*;
import java.awt.*;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;/*** 绘制箭头** @author xiangqian* @date 16:00 2019/10/31*/
public class DrawArrow {/*** 绘制面板** @author xiangqian* @date 15:38 2019/11/03*/public static class DrawPanel extends JPanel {private BasicStroke lineStroke;public DrawPanel() {lineStroke = new BasicStroke(2.0f);}@Overrideprotected void paintComponent(Graphics g) {draw((Graphics2D) g);}/*** 绘制** @param g2d*/private void draw(Graphics2D g2d) {Line2D.Double line2D = null;Arrow.Attributes arrowAttributes = null;// 绘制线的“方向1”箭头line2D = new Line2D.Double(120, 100, 300, 300);arrowAttributes = new Arrow.Attributes();drawLineArrowDirection1(g2d, arrowAttributes, line2D);// 绘制线的“方向2”箭头line2D = new Line2D.Double(110, 330, 300, 330);arrowAttributes = new Arrow.Attributes();arrowAttributes.angle = 45;arrowAttributes.height = 80;drawLineArrowDirection2(g2d, arrowAttributes, line2D);// 绘制线的“双向”箭头line2D = new Line2D.Double(500, 200, 260, 200);arrowAttributes = new Arrow.Attributes();arrowAttributes.angle = 30;arrowAttributes.height = 40;drawLineArrowDirectionAll(g2d, arrowAttributes, line2D);}/*** 绘制线的“方向1”箭头** @param g2d* @param arrowAttributes 箭头属性* @param line2D 线*/private void drawLineArrowDirection1(Graphics2D g2d, Arrow.Attributes arrowAttributes, Line2D.Double line2D) {drawLine(g2d, line2D);drawArrow(g2d, arrowAttributes, line2D.getP1(), line2D.getP2());}/*** 绘制线的“方向2”箭头** @param g2d* @param arrowAttributes 箭头属性* @param line2D 线*/private void drawLineArrowDirection2(Graphics2D g2d, Arrow.Attributes arrowAttributes, Line2D.Double line2D) {drawLine(g2d, line2D);drawArrow(g2d, arrowAttributes, line2D.getP2(), line2D.getP1());}/*** 绘制线的“双向”箭头** @param g2d* @param arrowAttributes 箭头属性* @param line2D 线*/private void drawLineArrowDirectionAll(Graphics2D g2d, Arrow.Attributes arrowAttributes, Line2D.Double line2D) {drawLine(g2d, line2D);drawArrow(g2d, arrowAttributes, line2D.getP1(), line2D.getP2());drawArrow(g2d, arrowAttributes, line2D.getP2(), line2D.getP1());}/*** 绘制线** @param g2d* @param line2D*/private void drawLine(Graphics2D g2d, Line2D.Double line2D) {g2d.setColor(Color.BLACK);g2d.setStroke(lineStroke);g2d.draw(line2D);}/*** 绘制箭头** @param g2d* @param arrowAttributes 箭头属性* @param point1 线的第一个点* @param point2 线的第二个点*/private void drawArrow(Graphics2D g2d, Arrow.Attributes arrowAttributes, Point2D point1, Point2D point2) {// 获取Arrow实例Arrow arrow = getArrow(arrowAttributes, point1, point2);// 构建GeneralPathGeneralPath arrow2D = new GeneralPath();arrow2D.moveTo(arrow.point1.x, arrow.point1.y);arrow2D.lineTo(arrow.point2.x, arrow.point2.y);arrow2D.lineTo(arrow.point3.x, arrow.point3.y);arrow2D.closePath();// 绘制g2d.setColor(arrow.attributes.color);g2d.fill(arrow2D);}/*** 获取箭头实体类** @param arrowAttributes 箭头属性* @param point1 线的第一个点* @param point2 线的第二个点* @return*/private Arrow getArrow(Arrow.Attributes arrowAttributes, Point2D point1, Point2D point2) {Arrow arrow = new Arrow(arrowAttributes);// 计算斜边double hypotenuse = arrow.attributes.height / Math.cos(Math.toRadians(arrow.attributes.angle / 2));// 计算当前线所在的象限int quadrant = -1;if (point1.getX() > point2.getX() && point1.getY() < point2.getY()) {quadrant = 1;} else if (point1.getX() < point2.getX() && point1.getY() < point2.getY()) {quadrant = 2;} else if (point1.getX() < point2.getX() && point1.getY() > point2.getY()) {quadrant = 3;} else if (point1.getX() > point2.getX() && point1.getY() > point2.getY()) {quadrant = 4;}// 计算线的夹角double linAngle = getLineAngle(point1.getX(), point1.getY(), point2.getX(), point2.getY());if (Double.isNaN(linAngle)) {// 线与x轴垂直if (point1.getX() == point2.getX()) {if (point1.getY() < point2.getY()) {linAngle = 90;} else {linAngle = 270;}quadrant = 2;}}// 线与y轴垂直else if (linAngle == 0) {if (point1.getY() == point2.getY()) {if (point1.getX() < point2.getX()) {linAngle = 0;} else {linAngle = 180;}quadrant = 2;}}// 上侧一半箭头double xAngle = linAngle - arrow.attributes.angle / 2; // 与x轴夹角double py0 = hypotenuse * Math.sin(Math.toRadians(xAngle)); // 计算y方向增量double px0 = hypotenuse * Math.cos(Math.toRadians(xAngle)); // 计算x方向增量// 下侧一半箭头double yAngle = 90 - linAngle - arrow.attributes.angle / 2; // 与y轴夹角double px1 = hypotenuse * Math.sin(Math.toRadians(yAngle));double py1 = hypotenuse * Math.cos(Math.toRadians(yAngle));// 第一象限if (quadrant == 1) {px0 = -px0;px1 = -px1;} else if (quadrant == 2) {// do nothing} else if (quadrant == 3) {py0 = -py0;py1 = -py1;} else if (quadrant == 4) {py0 = -py0;px0 = -px0;px1 = -px1;py1 = -py1;}// buildarrow.point1 = new Point2D.Double();arrow.point1.x = point1.getX();arrow.point1.y = point1.getY();arrow.point2 = new Point2D.Double();arrow.point2.x = point1.getX() + px0;arrow.point2.y = point1.getY() + py0;arrow.point3 = new Point2D.Double();arrow.point3.x = point1.getX() + px1;arrow.point3.y = point1.getY() + py1;return arrow;}/*** 获取线与X轴的夹角** @param x1* @param y1* @param x2* @param y2* @return*/protected double getLineAngle(double x1, double y1, double x2, double y2) {double k1 = (y2 - y1) / (x2 - x1);double k2 = 0;return Math.abs(Math.toDegrees(Math.atan((k2 - k1) / (1 + k1 * k2))));}}/*** 箭头实体类** @author xiangqian* @date 16:06 2019/10/31*/public static class Arrow {Attributes attributes;Point2D.Double point1;Point2D.Double point2;Point2D.Double point3;public Arrow(Attributes attributes) {this.attributes = attributes;}/*** 箭头属性** @author xiangqian* @date 15:41 2019/11/03*/public static class Attributes {double height; // 箭头的高度double angle; // 箭头角度Color color; // 箭头颜色public Attributes() {this.height = 60;this.angle = 30;this.color = Color.BLACK;}}}public static void main(String[] args) {JFrame frame = new JFrame();frame.setTitle("绘制箭头");Dimension dimension = new Dimension(800, 600);frame.setSize(dimension);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setContentPane(new DrawPanel());frame.setVisible(true);}}
效果展示
Java Swing绘制箭头相关推荐
- 仿金山打字通游戏,模拟键盘(java swing),提示输入,导入本地txt文件
一.设计思路 1.用一个主窗体,在主窗体上放置两个子窗体,一个是文本面板,一个是模拟键盘面板. 2.文本面板分两个子面板,一个是已有文本,一个是输入文本,在带输入文本面板上添加文件监听器,动态改变下一 ...
- java国际象棋棋牌_java使用swing绘制国际象棋棋盘
本文实例为大家分享了java使用swing绘制国际象棋棋盘的具体代码,供大家参考,具体内容如下 1.完整代码 import java.awt.Color; import java.awt.Point; ...
- Java Swing中的聊天气泡
本文将向您解释"如何在Java swing应用程序中绘制聊天气泡?" 聊天气泡与呼出气泡或思想气泡相同. 今天,大多数聊天应用程序都以这种格式显示转换,因此本文将帮助您在用Java ...
- MindFusion教程:Charting for Java Swing中的FunctionSeries
MindFusion.Diagramming for WinForms是一个能帮助你创建工作流和进程图表的.NET控件:数据库实体关系图表:组织图表:对象层次和关系图表:图表和树.它是基于对象-图表框 ...
- python画箭头opencv_OpenCV绘制箭头线
OpenCV绘制箭头线 可以使用imgproc类的arrowedLine()方法在图像上绘制箭头线. 以下是这种方法的语法 - arrowedLine(Mat img, Point pt1, Poin ...
- java swing 聊天气泡_Java Swing中的聊天气泡
本文将向您解释"如何在Java swing应用程序中绘制聊天气泡?" 聊天气泡与呼出气泡或思想气泡相同. 今天,大多数聊天应用程序都以这种格式显示转换,因此本文将帮助您在用Java ...
- 史上最扯Java图形绘制(J2SE)之一JAVA动画效果
很多主一听说Java界面,一水的头大外带血压高,兄弟我倒觉得没什么必要. 其实Java这东西吧,就简便性和其初衷而言,真他妈就在GUI 这地界是有优势的,单就其2D界面开发的易用性 ...
- 客户端是选择Java Swing还是C# Winform
登录 | 注册 mentat的专栏 目录视图 摘要视图 订阅 [专家问答]韦玮:Python基础编程实战专题 [知识库]Swift资源大集合 [公告]博客新皮肤上线啦 快来领福 ...
- java swing 一闪而过_Java代码,为什么图形会一闪而过,怎么修改?
//未完成:会一闪而过importjava.awt.*;importjava.awt.event.*;importjavax.swing.*;importjava.awt.geom.*;publicc ...
- java包裹邮费计算_GitHub - honghailiang/FreightSystem: 基于Java Swing编写的简易运费计算工具...
FreightSystem 基于java Swing编写的运费计算系统 初始化数据 从excel中读取数据,转化为对象(只保存基础数据:序列号.始发站.目的站.省份.100kg以下(元/kg).100 ...
最新文章
- SpringCloud03 Ribbon知识点、 Feign知识点、利用RestTemplate+Ribbon调用远程服务提供的资源、利用feign调用远程服务提供的资源、熔断...
- git分支建立删除,打tag
- arcengine动态显示所需字段值
- android ios 传视频播放器,推荐用于iOS / Android全面格式的视频播放器|手机最强大的播放器...
- 【目瞪口呆】通信机房内部长这样
- (亲测)躺着破解IDM下载权限,治疗不用破解补丁的强迫症们
- word批量转PDF
- 基于FPGA打地鼠游戏的设计与实现
- 【时间与空间】基本概念
- Pick peaks
- flutter开发的即时聊天应用
- 数据分析师必须掌握的模型——AARRR漏斗模型
- 2020复旦机试题:斗牛
- seosem是什么意思?
- 【JAVA】7-1 厘米换算英尺英寸
- NAND、NOR、FLASH、Memory
- 干货!如何在SCI论文中转述和总结别人的论文和成果
- qq登录测试用例(功能性测试、登录界面、性能、安全性、可用性、兼容性)
- linux 根文件系统满了,Solaris 10下根文件系统满的处理方法
- 移动互联网应用技术架构简介-Restful服务