java二維座標動態曲線圖繪製
阿新 • • 發佈:2019-01-30
將一串隨機數輸入到二維座標軸中,不斷重新整理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(); } }