Java实现的二维坐标趋势图(血压变化趋势图)

一、程序说明


1、自定义血压变化趋势图class MyCanvas 继承 Canvas类,重写其中的public void paint(Graphics g)方法,里边绘制详细的界面组件外观。

2、主类TrendChart 继承 JFrame,设定布局,添加文本框和输入框,实例化类产生对象trendChartCanvas,并将rendChartCanvas添加到中央区。

3、程序中的难点:绘制动态高压、低压线,这些数值源自int[] CurrentHighPressInput,int[] CurrentLowPressInput,编辑框中每次输入的数值更新到本数组。


二、运行效果

Java实现的二维坐标趋势图(血压变化趋势图)_第1张图片


三、源代码

package GraphicsCanvas;

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;

/**
 * 血压变化趋势图,包括坐标轴,高压、低压基准线,动态高压、低压线,分度值等
 * 
 * @author Freedoman
 * @Time 2014-1-1
 */
public class TrendChart extends JFrame {

	private static final long serialVersionUID = 1L;
	private Image iBuffer;
	private MyCanvas trendChartCanvas = new MyCanvas();
	private JTextField highPressText, lowPressText;

	// 框架起点坐标、宽高
	private final int FRAME_X = 100;
	private final int FRAME_Y = 100;
	private final int FRAME_WIDTH = 700;
	private final int FRAME_HEIGHT = 250;

	// 原点坐标
	private final int Origin_X = FRAME_X + 40;
	private final int Origin_Y = FRAME_Y + FRAME_HEIGHT - 30;

	// X轴、Y轴终点坐标
	private final int XAxis_X = FRAME_X + FRAME_WIDTH - 30;
	private final int XAxis_Y = Origin_Y;
	private final int YAxis_X = Origin_X;
	private final int YAxis_Y = FRAME_Y + 30;

	// X轴上的时间分度值(1分度=2天=40像素)
	private final int TIME_INTERVAL = 40;

	// y轴上血压分度值
	private final int PRESS_INTERVAL = 10;

	// 保存当前测量高压和低压值数组,数组长度计数器
	private int[] CurrentHighPressInput = { 150, 150, 150, 150, 150, 150, 150,
			150, 150, 150, 150, 150, 150, 150, 150, 150 };
	private int[] CurrentLowPressInput = { 75, 75, 75, 75, 75, 75, 75, 75, 75,
			75, 75, 75, 75, 75, 75, 75, 75, 75, 75, 75 };
	private int CurrentPressInputLength = 1;

	public TrendChart() {

		super("自定义血压趋势坐标图-FreeDoman");
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setBounds(300, 100, 900, 600);

		// 添加控制到框架北部区
		JPanel topPanel = new JPanel();
		this.add(topPanel, BorderLayout.NORTH);

		// 高压值与文本框
		highPressText = new JTextField(5);
		topPanel.add(new JLabel("高压值", JLabel.CENTER));
		topPanel.add(highPressText);

		// 低压值与文本框
		lowPressText = new JTextField(5);
		topPanel.add(new JLabel("低压值", JLabel.CENTER));
		topPanel.add(lowPressText);

		// 打点按钮与事件
		JButton pressButton = new JButton("打点");
		pressButton.addActionListener(new ActionListener() {

			// 把当前输入的高压和低压值
			@Override
			public void actionPerformed(ActionEvent arg0) {

				// 绘制当前输入的高压趋势
				int InputHighPress = Integer.parseInt(highPressText.getText());
				int InputLowPress = Integer.parseInt(lowPressText.getText());
				CurrentHighPressInput[CurrentPressInputLength] = InputHighPress;
				CurrentLowPressInput[CurrentPressInputLength] = InputLowPress;
				CurrentPressInputLength++;
				trendChartCanvas.repaint();
				// 输入文本框清零
				highPressText.setText("");
				lowPressText.setText("");
			}
		});

		topPanel.add(pressButton);

		// 添加画布到中央区
		this.add(trendChartCanvas, BorderLayout.CENTER);
		this.setResizable(false);
		this.setVisible(true);
	}

	/**
	 * 画布重绘血压趋势图
	 */
	class MyCanvas extends Canvas {
		
		private static final long serialVersionUID = 1L;
		public void paint(Graphics g) {
			Graphics2D g2D = (Graphics2D) g;

			// 画边框
			g.setColor(Color.BLACK);
			g.draw3DRect(FRAME_X, FRAME_Y, FRAME_WIDTH, FRAME_HEIGHT, true);

			// 画坐标轴
			g.setColor(Color.BLACK);
			g2D.setStroke(new BasicStroke(Float.parseFloat("2.0f")));
			// X轴及方向箭头
			g.drawLine(Origin_X, Origin_Y, XAxis_X, XAxis_Y);
			g.drawLine(XAxis_X, XAxis_Y, XAxis_X - 5, XAxis_Y - 5);
			g.drawLine(XAxis_X, XAxis_Y, XAxis_X - 5, XAxis_Y + 5);
			// Y轴及方向箭头
			g.drawLine(Origin_X, Origin_Y, YAxis_X, YAxis_Y);
			g.drawLine(YAxis_X, YAxis_Y, YAxis_X - 5, YAxis_Y + 5);
			g.drawLine(YAxis_X, YAxis_Y, YAxis_X + 5, YAxis_Y + 5);

			// 画X轴上时间刻度(从坐标原点起,每隔TIME_INTERVAL(时间分度)像素画一时间点,到X轴终点至)
			g.setColor(Color.BLUE);
			g2D.setStroke(new BasicStroke(Float.parseFloat("1.0f")));
			for (int i = Origin_X, j = 0; i < XAxis_X; i += TIME_INTERVAL, j += 2) {
				g.drawString("1-" + j, i - 10, Origin_Y + 20);
			}
			g.drawString("日期", XAxis_X + 5, XAxis_Y + 5);

			// 画Y轴上血压刻度(从坐标原点起,每隔10像素画一压力值,到Y轴终点至)
			for (int i = Origin_Y, j = 0; i > YAxis_Y; i -= PRESS_INTERVAL, j += 10) {
				g.drawString(j + "", Origin_X - 30, i + 3);
			}
			g.drawString("血压/mmgh", YAxis_X - 5, YAxis_Y - 5);

			// 画网格线
			g.setColor(Color.BLACK);
			// 横线
			for (int i = Origin_Y - PRESS_INTERVAL; i > YAxis_Y; i -= PRESS_INTERVAL) {
				g.drawLine(Origin_X, i, Origin_X + 15 * TIME_INTERVAL, i);
			}
			// 竖线
			for (int i = Origin_X + TIME_INTERVAL; i < XAxis_X; i += TIME_INTERVAL) {
				g.drawLine(i, Origin_Y, i, Origin_Y - 18 * PRESS_INTERVAL);

			}

			// 理想血压基准线
			// 高压
			g.setColor(Color.MAGENTA);
			g2D.setStroke(new BasicStroke(Float.parseFloat("2.0f")));
			g.drawLine(Origin_X, Origin_Y - 150, Origin_X + 15 * TIME_INTERVAL,
					Origin_Y - 150);
			g2D.setStroke(new BasicStroke(Float.parseFloat("1.0f")));
			g.drawString("理想高压线", Origin_X + 15 * TIME_INTERVAL + 3,
					Origin_Y - 150 + 3);
			// 低压
			g.setColor(Color.CYAN);
			g2D.setStroke(new BasicStroke(Float.parseFloat("2.0f")));
			g.drawLine(Origin_X, Origin_Y - 75, Origin_X + 15 * TIME_INTERVAL,
					Origin_Y - 75);
			g2D.setStroke(new BasicStroke(Float.parseFloat("1.0f")));
			g.drawString("理想低压线", Origin_X + 15 * TIME_INTERVAL + 3,
					Origin_Y - 75 + 3);

			// 当前测量高压线,循环画出高压数组CurrentHighPressInput[]中保存的线段
			g.setColor(Color.ORANGE);
			g2D.setStroke(new BasicStroke(Float.parseFloat("3.0f")));

			// 当前高压起点横坐标为CurrentHighPressStart_X,纵坐标为数组第一个,当前终点横坐标为CurrentHighPressStart_X
			// + TIMA_INTERVAL,纵坐标为数组第二个,依次类推画出各线段
			for (int i = 1, CurrentHighPressStart_X = Origin_X; i < CurrentPressInputLength; i++, CurrentHighPressStart_X += TIME_INTERVAL) {
				g.drawLine(CurrentHighPressStart_X, Origin_Y
						- CurrentHighPressInput[i - 1], CurrentHighPressStart_X
						+ TIME_INTERVAL, Origin_Y - CurrentHighPressInput[i]);
			}

			// 当前测量低压线,循环画出低压数组CurrentLowPressInput[]中保存的线段
			g.setColor(Color.PINK);
			g2D.setStroke(new BasicStroke(Float.parseFloat("3.0f")));
			// 当前低压起点横坐标为CurrentHighPressStart_X,纵坐标为数组第一个,当前终点横坐标为CurrentLowPressStart_X
			// + TIMA_INTERVAL,纵坐标为数组第二个,依次类推画出各线段
			for (int i = 1, CurrentLowPressStart_X = Origin_X; i < CurrentPressInputLength; i++, CurrentLowPressStart_X += TIME_INTERVAL) {
				g.drawLine(CurrentLowPressStart_X, Origin_Y
						- CurrentLowPressInput[i - 1], CurrentLowPressStart_X
						+ TIME_INTERVAL, Origin_Y - CurrentLowPressInput[i]);
			}
		}

		// 双缓冲技术解决图像显示问题
		public void update(Graphics g) {
			if (iBuffer == null) {
				iBuffer = createImage(this.getSize().width,
						this.getSize().height);

			}
			Graphics gBuffer = iBuffer.getGraphics();
			gBuffer.setColor(getBackground());
			gBuffer.fillRect(0, 0, this.getSize().width, this.getSize().height);
			paint(gBuffer);
			gBuffer.dispose();
			g.drawImage(iBuffer, 0, 0, this);
		}
	}

	public static void main(String[] args) {

		// 设置界面的外观,为系统外观
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch (Exception e) {
			e.printStackTrace();
		}

		new TrendChart();
	}
}

你可能感兴趣的:(Java)