java 绘制动态的图形

it2022-05-05  162

效果如下

代码如下(初始版本)

package cn.com.com; 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 Test extends JPanel { // 动态的绘图 public static void main(String[] args) { // 0.设置窗体的内容 JFrame jf = new JFrame("JAVA动态图形"); // 1.设置一下窗体的宽高情况 jf.setSize(500, 500); // 获取面板的内容 jf.getContentPane().add(new Test()); // 2.设置关闭窗体就是关闭线程 jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 3.设置可见 jf.setVisible(true); } /* * 集合 最大的容纳量 值 */ private static List<Integer> list; private static int size = 60; private static int value = 100; // 2.一个动态的集合 public Test() { list = Collections.synchronizedList(new ArrayList<Integer>()); new Thread(new Runnable() { public void run() { // TODO Auto-generated method stub while (true) { // 2.1首先判断能不能添加,如果不能首先移除 if (list.size() > size) { list.remove(0);// 移除第一个数据 } // 2.1.1 产生一个随机数 Random r = new Random(); // 2.1.2 把数放在集合里面 System.out.println(r.nextInt(100)); list.add(r.nextInt(100)); // 2.2绘制的开始设置x,y /* * 在绘制动画图形时候如果没有调用repaint()方法的时候直接就是由线程调用 * 这个需要线程,不然没有效果 */ repaint(); // 2.3延迟0.1s,不然的话页面绘制图片会显得有突兀 try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }).start(); } // 3 绘制一下 @Override public void paintComponent(Graphics g) { super.paintComponent(g); // 准备绘制 Graphics2D g2d = (Graphics2D) g; // 设置绘制线条的质量 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 设置宽高 // 设置宽高 int x = getHeight() / size; int y = getWidth() / value; int len = list.size(); // 开始循环遍历数据 for (int i = 0; i < len - 1; i++) { g2d.drawLine(x * (size - len + i), y * list.get(i), x * (size - len + i + 1), y * list.get(i + 1)); } } }

代码如下(规范版本)

package cn.com.com; import javax.swing.*; import java.awt.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Random; /*author:命运的信徒 * date:2019.7.18 * arm:java动态绘图的方法 */ public class Plaint extends JPanel { private List<Integer> values; // 存储数据的集合,线程不安全 private static final int MAX_VALUE = 200; // 最大值(限制里面的y数据) private static final int MAX_COUNT_OF_VALUES = 50; // 集合的最大容量 public Plaint() { //一个线程安全的集合 values = Collections.synchronizedList(new ArrayList<Integer>()); // 使用线程的目的,动态的,可以往集合里面添加和去除数据 new Thread(new Runnable() { public void run() { //一个随机数,准确的说是小于200的 Random rand = new Random(); try { while (true) { //生成的数添加集合,如果集合里面的数据多了就剔除数据 addValue(rand.nextInt(MAX_VALUE)); // 产生一个数据,并模拟接收并放到容器里. System.out.println("线程"); //这个是一个重绘的方法,是线程安全的;可以调用paintComponent(Graphics g) 方法 repaint(); Thread.sleep(100); } } catch (InterruptedException e) { e.printStackTrace(); } } }).start(); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); //准备绘制 Graphics2D g2d = (Graphics2D) g; //设置绘制线条的质量 g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //设置宽高 int w = getWidth(); int h = getHeight(); //设置x轴方向的单位长度;如果宽400px,设置最大的数据容量是50;那么一个数据就占据8px int xDelta = w / MAX_COUNT_OF_VALUES; //这个是集合的实时长度,肯定是小于或等于MAX_COUNT_OF_VALUES int length = values.size(); //对集合里面的数据进行绘制,第一个点和第二个点要连线 for (int i = 0; i < length - 1; ++i) { /* * x轴的位置:xDelta * (MAX_COUNT_OF_VALUES - length + i) 如果集合的数据没有溢出来,一定是最后一个是最右边,第一个是集合的最大长度-集合当前长度+1; * y轴的位置:normalizeValueForYAxis(values.get(i), h) * 前一个数据和后一个数据相连接 */ g2d.drawLine(xDelta * (MAX_COUNT_OF_VALUES - length + i), normalizeValueForYAxis(values.get(i), h), xDelta * (MAX_COUNT_OF_VALUES - length + i + 1), normalizeValueForYAxis(values.get(i + 1), h)); } } /** * 接收到的数据放入内存. * @param value */ private void addValue(int value) { // 循环的使用一个接收数据的空间. // 最好是实现一个循环数组,而不是偷懒的使用ArrayList. if (values.size() > MAX_COUNT_OF_VALUES) { values.remove(0); } values.add(value); } /** * 规一化y轴方向的值. 使得value在y轴的值为[0, height]之间. */ private int normalizeValueForYAxis(int value, int height) { return (int) ((double) height / MAX_VALUE * value); } private static void createGuiAndShow() { //窗体的名称 JFrame frame = new JFrame("java动态绘制图形"); //内容 frame.getContentPane().add(new Plaint()); //设置关闭窗体就是关闭整个程序 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //设置窗体的大小 frame.setSize(600, 600); frame.setLocationRelativeTo(null); //设置窗体可见 frame.setVisible(true); } public static void main(String[] args) { createGuiAndShow(); } }

 


最新回复(0)