超轻量Swing仪表盘组件

XDoc发布了8.2.5版本,新版本中增加了扩展组件:刻度盘,用于动态图示化展示数据
现在将它封装成一个Swing组件与大家分享,大家可以稍做调整画出更漂亮的仪表盘
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 刻度盘
* @author xdoc
*/
public class Tick extends JComponent {
private static final int VALUE_FONT_SIZE = 18;
private double from = 0;
private double to = 10;
private String type = "line";
private double major = 1;
private double minor = 0.1;
private String value = "";
private String unit = "";
public double getFrom() {
return from;
}
public Tick() {
super();
this.setPreferredSize(new Dimension(60, 60));
this.setBackground(Color.WHITE);
}
public void setFrom(double from) {
this.from = from;
}
public double getMajor() {
return major;
}
public void setMajor(double major) {
this.major = major;
}
public double getMinor() {
return minor;
}
public void setMinor(double minor) {
this.minor = minor;
}
public double getTo() {
return to;
}
public void setTo(double to) {
this.to = to;
}
public String getType() {
return type;
}
/**
* 直尺
*/
public static final String LINE = "line";
/**
* 120度圆环
*/
public static final String RING_120 = "ring120";
public static final String RING_180 = "ring180";
public static final String RING_240 = "ring240";
/**
* 圆盘
*/
public static final String CIRCLE = "circle";
public void setType(String type) {
this.type = type;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public void paintComponent(Graphics g) {
double w = this.getWidth();
double h = this.getHeight();
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(this.getBackground());
g2.fillRect(0, 0, (int) w, (int) h);
g2.setColor(this.getForeground());
g2.setStroke(new BasicStroke(1));
int fontSize = 14;
g2.setFont(new Font(Font.SERIF, Font.PLAIN, fontSize));
if (major <= 0) {
major = to - from;
}
if (to > from) {
if (type.startsWith("ring") || type.equals("circle")) {
double angle;
double angleStart;
if (type.equals("circle")) {
angle = 360;
angleStart = Math.PI / 2;
} else {
angle = toDouble(type.substring(4));
angleStart = (180 + (angle - 180) / 2) / 180 * Math.PI;
}
double r = angle <= 180 ? Math.min(w / 2, h) : Math.min(w / 2, h / 2);
double voff = angle <= 180 ? 0 : r;
double dunit = (angle / 180 * Math.PI) / (to - from);
for (int i = 0; i <= (to - from) / major; i++) {
g2.draw(new Line2D.Double(Math.cos(angleStart - i * major * dunit) * r + w / 2, h - voff - Math.sin(angleStart - i * major * dunit) * r,
Math.cos(angleStart - i * major * dunit) * r * 0.75 + w / 2, h - voff - Math.sin(angleStart - i * major * dunit) * r * 0.75));
if (minor > 0 && i < (to - from) / major) {
for (int j = 1; j < major / minor; j++) {
if (i * major + j * minor < to - from) {
g2.draw(new Line2D.Double(Math.cos(angleStart - (i * major + j * minor) * dunit) * r + w / 2, h - voff - Math.sin(angleStart - (i * major + j * minor) * dunit) * r,
Math.cos(angleStart - (i * major + j * minor) * dunit) * r * 0.875 + w / 2, h - voff - Math.sin(angleStart - (i * major + j * minor) * dunit) * r * 0.875));
}
}
}
}
if (value.length() > 0) {
double val = toDouble(value);
GeneralPath p = new GeneralPath();
p.moveTo(Math.cos(angleStart - (val - from) * dunit) * r * 0.875 + w / 2, h - voff - Math.sin(angleStart - (val - from) * dunit) * r * 0.875);
p.lineTo(Math.cos(angleStart - (val - from) * dunit + Math.PI * 0.5) * 2 + w / 2, h - voff - Math.sin(angleStart - (val - from) * dunit + Math.PI * 0.5) * 2);
p.lineTo(Math.cos(angleStart - (val - from) * dunit - Math.PI * 0.5) * 2 + w / 2, h - voff - Math.sin(angleStart - (val - from) * dunit - Math.PI * 0.5) * 2);
p.closePath();
g2.fill(p);
}
} else {
if (w > h) {
double dunit = w / (to - from);
for (int i = 0; i <= (to - from) / major; i++) {
g2.draw(new Line2D.Double(i * major * dunit, 0, i * major * dunit, h - fontSize));
if (i < (to - from) / major && minor > 0) {
for (int j = 1; j < major / minor; j++) {
g2.draw(new Line2D.Double((i * major + j * minor) * dunit, 0, (i * major + j * minor) * dunit, (h - fontSize) / 2));
}
}
}
if (value.length() > 0) {
double val = toDouble(value);
GeneralPath p = new GeneralPath();
p.moveTo((val - from) * dunit, (h - fontSize) / 2);
p.lineTo((val - from) * dunit - 4, h - fontSize);
p.lineTo((val - from) * dunit + 4, h - fontSize);
p.closePath();
g2.fill(p);
}
} else {
int max = (int) Math.max(getStrBounds(g2, format(from)).getWidth(), getStrBounds(g2, format(to)).getWidth());
double dunit = h / (to - from);
for (int i = 0; i <= (to - from) / major; i++) {
g2.draw(new Line2D.Double(0, h - i * major * dunit, w - max, h - i * major * dunit));
if (i < (to - from) / major && minor > 0) {
for (int j = 1; j < major / minor; j++) {
g2.draw(new Line2D.Double(0, h - (i * major + j * minor) * dunit, (w - max) / 2, h - (i * major + j * minor) * dunit));
}
}
}
if (value.length() > 0) {
double val = toDouble(value);
GeneralPath p = new GeneralPath();
p.moveTo((w - max) / 2, h - (val - from) * dunit);
p.lineTo(w - max, h - (val - from) * dunit - 4);
p.lineTo(w - max, h - (val - from) * dunit + 4);
p.closePath();
g2.fill(p);
}
}
}
}
if (to > from) {
if (major > 0) {
if (type.startsWith("ring") || type.equals("circle")) {
double angle;
double angleStart;
if (type.equals("circle")) {
angle = 360;
angleStart = Math.PI / 2;
} else {
angle = toDouble(type.substring(4));
angleStart = (180 + (angle - 180) / 2) / 180 * Math.PI;
}
double r = angle <= 180 ? Math.min(w / 2, h) : Math.min(w / 2, h / 2);
double voff = angle <= 180 ? 0 : r;
double dunit = (angle / 180 * Math.PI) / (to - from);
int xoff = 0;
int yoff = 0;
double strAngle;
for (int i = type.equals("circle") ? 1 : 0; i <= (to - from) / major; i++) {
String str;
str = format(from + i * major);
strAngle = (angleStart - i * major * dunit + Math.PI * 2) % (Math.PI * 2);
xoff = 0;
yoff = 0;
if (strAngle >= 0 && strAngle < Math.PI * 0.25) {
xoff = (int) -getStrBounds(g2, str).getWidth();
yoff = fontSize / 2;
if (strAngle == 0 && angle == 180) {
yoff = 0;
}
} else if (near(strAngle, Math.PI * 0.5)) {
xoff = (int) -getStrBounds(g2, str).getWidth() / 2;
yoff = fontSize;
} else if (strAngle >= Math.PI * 0.25 && strAngle < Math.PI * 0.5) {
xoff = (int) -getStrBounds(g2, str).getWidth();
yoff = fontSize;
} else if (strAngle >= Math.PI * 0.5 && strAngle < Math.PI * 0.75) {
yoff = fontSize;
} else if (strAngle >= Math.PI * 0.75 && strAngle < Math.PI) {
yoff = fontSize / 2;
} else if (near(strAngle, Math.PI)) {
xoff = 1;
yoff = fontSize / 2;
if (angle == 180) {
yoff = 0;
}
} else if (strAngle >= Math.PI && strAngle < Math.PI * 1.25) {
yoff = fontSize / 4;
} else if (near(strAngle, Math.PI * 1.5)) {
xoff = (int) -getStrBounds(g2, str).getWidth() / 2;
} else if (strAngle >= Math.PI * 1.5 && strAngle < Math.PI * 2) {
xoff = (int) -getStrBounds(g2, str).getWidth();
}
g2.drawString(str, (int) (Math.cos(strAngle) * r * 0.75 + w / 2) + xoff, (int) (h - voff - Math.sin(strAngle) * r * 0.75) + yoff);
}
g2.setFont(new Font("", Font.BOLD, VALUE_FONT_SIZE));
if (value.length() > 0) {
voff = angle <= 180 ? 10 : r - fontSize / 2;
drawValue(g2, value + unit, (int) (w / 2 - getStrBounds(g2, value).getWidth() / 2), (int) (h - voff));
}
} else {
if (w > h) {
double dunit = w / (to - from);
int off = 0;
String str;
for (int i = 0; i <= (to - from) / major; i++) {
str = format(from + i * major);
if (i == 0) {
str += unit;
off = 0;
} else if (i == (to - from) / major) {
off = (int) -getStrBounds(g2, str).getWidth();
} else {
off = (int) (-getStrBounds(g2, str).getWidth() / 2);
}
g2.drawString(str, (int) (i * major * dunit) + off, (int) (h - 2));
}
if (value.length() > 0) {
double val = toDouble(value);
value = format(val);
if (val == from) {
off = 0;
} else if (val == to) {
off = (int) -getStrBounds(g2, value + unit).getWidth();
} else {
off = (int) (-getStrBounds(g2, value + unit).getWidth() / 2);
}
if ((h - fontSize) / 2 >= fontSize) {
drawValue(g2, value + unit, (int) ((val - from) * dunit) + off, (int) ((h - fontSize) / 2));
} else {
drawValue(g2, value + unit, (int) ((val - from) * dunit) + off, fontSize);
}
}
} else {
double dunit = h / (to - from);
int max = (int) Math.max(getStrBounds(g2, format(from)).getWidth(), getStrBounds(g2, format(to)).getWidth());
int off = 0;
for (int i = 0; i <= (to - from) / major; i++) {
if (i == 0) {
off = 0;
} else if (i == (to - from) / major) {
off = fontSize;
} else {
off = fontSize / 2;
}
g2.drawString(format(from + i * major), (int) (w - max + 1), (int) (h - i * major * dunit) + off);
}
if (unit.length() > 0) {
g2.drawString(unit, (int) ((w - max) / 2 + 1), (int) (h - fontSize));
}
if (value.length() > 0) {
double val = toDouble(value);
value = format(val);
if (val == 0) {
off = 0;
} else if (val == to) {
off = VALUE_FONT_SIZE;
} else {
off = VALUE_FONT_SIZE / 2;
}
drawValue(g2, value + unit, (int) ((w - getStrBounds(g2, value + unit).getWidth()) / 2), (int) (h - (val - from) * dunit + off));
}
}
}
}
}
}
private void drawValue(Graphics2D g2, String value, int x, int y) {
g2.setFont(new Font(Font.SERIF, Font.BOLD, VALUE_FONT_SIZE));
g2.drawString(value, x, y);
}
private String format(double d) {
if ((int) d == d) {
return String.valueOf((int) d);
} else {
return String.valueOf(d);
}
}
private double toDouble(String string) {
try {
return Double.valueOf(string);
} catch (Exception e) {
return 0;
}
}
private boolean near(double d1, double d2) {
return Math.round(d1 * 1000000) == Math.round(d2 * 1000000);
}
private static Rectangle2D getStrBounds(Graphics2D g, String str) {
Font f = g.getFont();
Rectangle2D rect = f.getStringBounds(str, g.getFontRenderContext());
if (rect.getHeight() < f.getSize()) {
rect.setFrame(rect.getX(), rect.getY(), rect.getWidth(), f.getSize() + 1);
}
return rect;
}
public static void main(String[] args) {
try {
JFrame f = new JFrame("刻度盘测试");
Container p = f.getContentPane();
Tick tick;
tick = new Tick();
tick.setType(Tick.LINE);
tick.setValue("3");
tick.setUnit("CM");
p.add(tick, BorderLayout.NORTH);
tick = new Tick();
tick.setType(Tick.LINE);
p.add(tick, BorderLayout.WEST);
JPanel panel = new JPanel(new GridLayout(2, 2));
tick = new Tick();
tick.setForeground(Color.BLUE);
tick.setType(Tick.RING_120);
tick.setValue("3.5");
tick.setUnit("A");
panel.add(tick);
tick = new Tick();
tick.setType(Tick.RING_180);
tick.setValue("6");
tick.setUnit("V");
panel.add(tick);
tick = new Tick();
tick.setType(Tick.RING_240);
tick.setValue("3");
tick.setUnit("Kg");
panel.add(tick);
tick = new Tick();
tick.setType(Tick.CIRCLE);
tick.setValue("3");
tick.setUnit("Kg");
tick.setBackground(Color.BLACK);
tick.setForeground(Color.WHITE);
panel.add(tick);
p.add(panel, BorderLayout.CENTER);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(640, 480);
f.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
}


[img]http://dl.iteye.com/upload/attachment/0067/3694/2b98f9b2-e155-30ab-a994-67d51a9f1941.png[/img]

虽然很简单,但放入XDoc中小虫就变小龙了,看看在XDoc中的表现吧:

[img]http://dl.iteye.com/upload/attachment/0067/3696/8778e611-03a5-3027-a292-2c194f5e4042.png[/img]
用JFreeChart实现仪表盘 JFreeChart是一个报表框架,可以实现各种各样的图表,例如:饼形图,柱形图,折线图,区域图,时序图,组合图,仪表盘等等 在这里我只实现几种不同的仪表盘 1,时钟 import java.awt.*; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.C 阅读详情

相关推荐

canvas写仪表盘

electricity.html 电压电流表 #meter_canvas1, #meter_canvas2, #meter_canvas3, #meter_canvas4, #meter_canvas5, #meter_canvas6{ background:url('img/hui.png

java_zhaoyanli的专栏 3935

基于Java Swing的仪表盘实现

序言 够几个月没有更新了,博客还透露着春招焦虑的气息。最近code确实不多,而且缺乏原创性的内容,当然,关键点还是在于,对于最近看的东西,看的比较杂,没能够有一个非常透彻的理解,input后没有进行很好的内化,导致output如难产的婴儿,迟迟无法落地。转到正题,这次写的仪表盘,继承JComponent实现一个仪表空间。支持直线性,弧形,...

weixin_34272308的博客 1012

SteelSeries java swing 仪表盘 指针 jar包及源码

丰富的仪表盘控件,实时显示数值,源码导入可直接运行,程序无bug,附可运行jar包

swing写的仪表盘

Dashboard

qq_24771601的博客 527

基于Swing的java仪表盘组件SteelSeries3.9.30

包括相关的源码和依赖库; test.zip中包含相关的实例

SwingX api 帮助文档

这是SwingX api的帮助文档,是html格式的,英文帮助文档,虽然是英文的,不过相信大部分人都可以轻易地看明白这个文档,使用SwingX组件。

基于swing的UI原型辅助设计

XDocOffice发布了8.2.2版本,新版本对swing元件进行了增强,增加对表格、树、菜单、工具条、滚动条、标签页等支持。 基于此可以使用XDocOffice进行UI原型辅助设计。使用附件中的swing组件库,将使操作更方便、高效。 XDocOffice地址:http://www.hgsql.com/XDocBuilder.asp 注意:使用前要导入附件中的swing组件库 ...

weixin_30892987的博客 169

java动态仪表盘显示

java做的查询显示页面,筛选报警页面,其中包括java动态仪表盘显示

分享超轻量Swing仪表盘组件(带源码)

http://www.iteye.com/topic/1123249 XDoc发布了8.2.5版本,新版本中增加了扩展组件:刻度盘,用于动态图示化展示数据 现在将它封装成一个Swing组件与大家分享,大家可以稍做调整画出更漂亮的仪表盘 import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.C

ycb1689的专栏 1118

java数字万用表识别

java实现万用表数字识别

飞腾X100芯片GPU状态查询

本文档对在linux系统下查看X100芯片GPU状态信息进行说明,可以帮助大家了解芯片的实时工作状态。

乌拉大喵喵 2817

java swing速度_绘制一个半量表/车速表(需要JavaScript Canvas或Java Swing示例)

我建议考虑在Raphael的Javascript图形库。它适用于所有浏览器(包括旧版本的IE!),并使用矢量图形,因此它生成的图形可扩展且可旋转,而不会损失图像质量,甚至还包含动画功能。但是,如果你想画你自己的,它不应该是很难用拉斐尔的事:它有绘制粒子和形状的能力,并为它们制作动画。看起来像你的例子的东西不应该很难实现。下面是一些代码,我赶紧敲一起作为一个例子:var gauge = Raphae...

weixin_42297446的博客 412

python cartopy绘制扇形区域图/cartopy绘制北极部分区域

实际上,这个问题原因还是由于投影转换的问题,在set_extend时,绘制的上下边界仍然是方形、未被正确投影的边界,与我们的set_boundary存在冲突,最根本的原因还是在于cartopy对于投影计算的一些缺陷。另外我们需要指出的是:**该方法不适用于极地投影,即NorthPolarStereo,由于NorthPolarStereo本身投影特性只需一个参数,本身并不适合。我们绘制极地投影时,同样也是使用set_boundary绘制圆形边界,那么当我们想要绘制扇形时,可以通过。请根据喜好自行选择,

weixin_43750300的博客 3212

mindfusion控件,时尚的图表|仪表和仪表板

mindfusion控件,时尚的图表|仪表和仪表板   MindFusion.Charting for Java Swing 让您可以组合和排列图表、仪表和 UI 元素,以创建高级数据可视化解决方案。该库附带一组预定义的图表,您可以轻松地填充数据并调整外观。   mindfusion控件用于 Java Swing 功能   mindfusion控件各种图表 -图表库附带一组预定义图表,您可以轻松地填充数据并调整外观。饼图和圆环图、雷达图、极坐标图和具有各种方向的条形图、漏斗图、气泡图等等。如果您更喜欢

q2315702359的博客 573

头歌操作系统2.3系统调用命令ls执行的系统调用

设置版本0内核为分析对象。然后一直c直到虚拟机出现。然后一直c就是答案了。

m0_74128952的博客 1万+

从JX-2R-01热敏打印机芯到稳定打印:硬件设计与时序控制的实践指南

本文详细解析了JX-2R-01热敏打印机芯的硬件设计与驱动开发全流程。核心内容包括:实现严格的双电源上电时序控制、采用PWM恒流驱动步进电机确保走纸平稳,以及精确控制SPI数据加载与加热脉冲时序以获得清晰打印效果。文章提供了从电路设计、芯片选型到代码调试的实战指南,旨在帮助开发者构建稳定可靠的热敏打印模块。

weixin_29169899的博客 223

Java Swing 应用简介——以温度显示界面为例

在Java中使用Swing来设计图形用户界面(GUI),使用Swing开发的Java应用程序,界面不受本地系统的限制,移植到其他平台上界面不会改变。 Swing的基本器件包括窗体(JFrame),面板(JPanel),组件(标签,列表,按钮……),我们可以可以这样理解三者间的关系:GUI就像一张桌子摆满了丰盛食物,JFrame就是这张桌子,组件就是桌子上不同的食物,而JPanel就是摆放这些食物...

weixin_42385626的博客 2016

三菱PLC FX3U温度控制系统案例

U0\G100是平均次数的设置,设置为100个数据取平均,这样数据显示更加稳定,通道1的数据显示再U0\G10里面,温度模块的数据对应是0~150°输出0~10V,对应到0~10000的数据10000是150°的66.667倍,因此把数据传送到D0后转换成浮点数,再去除以66.667,就得到实际的温度了,数据存放到D2。触摸屏软件使用EBpro软件,设计界面如下,右边的是温度的实时曲线图,左边的是温度报警表,当当前温度超过了报警温度这种时,就会在这个表格上显示对应对应的报警。(1)实时显示温度值;

u010670857的博客 4060

利用Java的swing+awt组件编写可运行的动态大小时钟小程序(简单高效,可随窗口大小变化而变化)

利用Java的swing+awt组件编写可运行的动态大小时钟小程序(简单高效,可随窗口大小变化而变化)

猪萌萌的博客 1303

ADS电路仿真方法综述:原理与应用

在射频与微波电路设计中,精确的仿真技术是验证性能的关键。ADS(Advanced Design System)作为行业标准工具,集成了多种仿真方法,适用于不同场景。本文将系统解析瞬态分析、谐波平衡(HB)、交流分析(AC)、直流分析(DC)、S参数、大信号SP(LSSP)及包络分析的原理、实现机制与应用场景。

u014344410的博客 482

【全局路径规划模块运动学算法】无人机Kinodynamic A*算法、Kinodynamic RRT*算法(附C++代码)

认知有限,望大家多多包涵,有什么问题也希望能够与大家多交流,共同成长!本文先对Kinodynamic A*算法做个简单的介绍,具体内容后续再更,其他模块可以参考去我其他文章提示:以下是本篇文章正文内容啃这个Kinodynamic A_star算法,建议先啃一啃高飞fast_planner那篇论文,把理论打好,如果还是比较迷,就先看Dijksta、再看A_star、再看hybrid A_star 三个的流程,因为往上资料比较多,再看这个Kinodynamic A_star算法,流程已经很相像了。如果。

qq_35635374的博客 2604

免费报表XDOC从入门到精通(三)第一个XDOC

创建 打开XDOC设计器,输入“第一个XDOC”,如下图:    部署 点击【服务器】,切换到服务器视图     切换到服务器视图后,显示连接到服务器对话框,如下图:     点击【确定】按钮。 点击【设计】,切换到设计视图     点击主工具条【保存】按钮,部署XDOC         切换到服务器视图...

295

PyTorch实战:卷积神经网络详解+Python实现卷积神经网络Cifar10彩色图片分类

PyTorch可以说是三大主流框架中最适合初学者学习的了,相较于其他主流框架,PyTorch的简单易用性使其成为初学者们的首选。这样我想要强调的一点是,框架可以类比为编程语言,仅为我们实现项目效果的工具,也就是我们造车使用的轮子,我们重点需要的是理解如何使用Torch去实现功能而不要过度在意轮子是要怎么做出来的,那样会牵扯我们太多学习时间。以后就出一系列专门细解深度学习框架的文章,但是那是较后期我们对深度学习的理论知识和实践操作都比较熟悉才好开始学习,现阶段我们最需要的是学会如何使用这些工具。

master_hunter的博客 8935
上一篇: 一份漂亮的健康体检报告(二)
下一篇: 绚烂的Java滤镜
sqlhub
博客等级 码龄21年 19粉丝 93原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值