1. 程式人生 > >java二維座標動態曲線圖繪製

java二維座標動態曲線圖繪製

將一串隨機數輸入到二維座標軸中,不斷重新整理JPanel,實現動態顯示的效果微笑

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Chart_test extends JFrame {

	private List<Integer> values;// 儲存接受的資料容器
	private static final int MAX_VALUE = 180;// 接受到的資料最大值
	private static final int MAX_COUNT_OF_VALUES = 50;// 最多儲存資料的個數
	// private
	private MyCanvas trendChartCanvas = new MyCanvas();
	// 框架起點座標
	private final int FREAME_X = 50;
	private final int FREAME_Y = 50;
	private final int FREAME_WIDTH = 600;// 橫
	private final int FREAME_HEIGHT = 250;// 縱

	// 原點座標
	private final int Origin_X = FREAME_X + 50;
	private final int Origin_Y = FREAME_Y + FREAME_HEIGHT - 30;

	// X,Y軸終點座標
	private final int XAxis_X = FREAME_X + FREAME_WIDTH - 30;
	private final int XAxis_Y = Origin_Y;
	private final int YAxis_X = Origin_X;
	private final int YAxis_Y = FREAME_Y + 30;

	// X軸上的時間分度值(1分度=40畫素)
	private final int TIME_INTERVAL = 50;
	// Y軸上值
	private final int PRESS_INTERVAL = 30;

	public Chart_test() {
		super("前端介面顯示:");
		values = Collections.synchronizedList(new ArrayList<Integer>());// 防止引起執行緒異常
		// 建立一個隨機數執行緒
		new Thread(new Runnable() {
			public void run() {
				Random rand = new Random();
				try {
					while (true) {
						addValue(rand.nextInt(MAX_VALUE) + 90);
						repaint();
						Thread.sleep(100);
					}
				} catch (InterruptedException b) {
					b.printStackTrace();
				}
			}

		}).start();

		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setBounds(300, 200, 900, 600);
		this.add(trendChartCanvas, BorderLayout.CENTER);
		this.setVisible(true);
	}

	public void addValue(int value) {
		// 迴圈的使用一個接受資料的空間
		if (values.size() > MAX_COUNT_OF_VALUES) {
			values.remove(0);
		}
		values.add(value);
	}

	// 畫布重繪圖
	class MyCanvas extends JPanel {
		private static final long serialVersionUID = 1L;

		public void paintComponent(Graphics g) {
			Graphics2D g2D = (Graphics2D) g;

			Color c = new Color(200, 70, 0);
			g.setColor(c);
			super.paintComponent(g);

			// 繪製平滑點的曲線
			g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
			int w = XAxis_X;// 起始點
			int xDelta = w / MAX_COUNT_OF_VALUES;
			int length = values.size() - 10;

			for (int i = 0; i < length - 1; ++i) {
				g2D.drawLine(xDelta * (MAX_COUNT_OF_VALUES - length + i), values.get(i),
						xDelta * (MAX_COUNT_OF_VALUES - length + i + 1), values.get(i + 1));
			}
			// 畫座標軸
			g2D.setStroke(new BasicStroke(Float.parseFloat("2.0F")));// 軸線粗度
			// X軸以及方向箭頭
			g.drawLine(Origin_X, Origin_Y, XAxis_X, XAxis_Y);// x軸線的軸線
			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")));

			// X軸刻度依次變化情況
			for (int i = Origin_X, j = 0; i < XAxis_X; i += TIME_INTERVAL, j += TIME_INTERVAL) {
				g.drawString(" " + 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 += TIME_INTERVAL) {
				g.drawString(j + " ", Origin_X - 30, i + 3);
			}
			g.drawString("幅度/Amplitude", YAxis_X - 5, YAxis_Y - 5);// 血壓刻度小箭頭值
			// 畫網格線
			g.setColor(Color.BLACK);
			// 座標內部橫線
			for (int i = Origin_Y; i > YAxis_Y; i -= PRESS_INTERVAL) {
				g.drawLine(Origin_X, i, Origin_X + 10 * TIME_INTERVAL, i);
			}
			// 座標內部豎線
			for (int i = Origin_X; i < XAxis_X; i += TIME_INTERVAL) {
				g.drawLine(i, Origin_Y, i, Origin_Y - 6 * PRESS_INTERVAL);
			}

		}
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new Chart_test();
	}
}