具有原始线图函数 Java 的动画线图
为了更多地了解小程序和 Java,我正在尝试通过绘制线条 (drawLine) 和制作动画折线图来制作波形小程序。
我可以很好地制作静态图。然而,我正在努力解决图表的动画方面:图表的轴应该从左向右移动,增加并增长到大于 0。
我的问题是将我的需求转化为解决方案。任何人都可以给我任何关于我的问题的指示吗?
我有一个多维数组,由包含特定点的 x 和 y 的点索引。我尝试修改我的渲染函数以减少 X,使其看起来好像向左移动,但这不起作用。
我希望采取什么方法?如果 Y 的值可能因用户操作或添加的数据而改变,我的方法会有多大不同?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
/**
* A graph that should in the future represent a wave according to my inputs
*
* @authorImprofane
* @version 1
*/
public class Graph extends JFrame
{
private InnerGraph inner;
private int width;
private Random RNG;
private int height;
private int[][] series;
private int xoffset;
int prevx = 0;
int prevy = 0;
/**
* Constructor for objects of class Graph
*/
public Graph(int width, int height) throws InterruptedException
{
RNG = new Random();
setTitle(" Graph");
series = new int[width][2];
this.width = width;
this.height = height;
inner = new InnerGraph(width, height);
add(inner, BorderLayout.CENTER);
setVisible(true);
inner.preparePaint();
pack();
updateGraph();
}
public static void main(String[] args) throws InterruptedException
{
new Graph(300, 300);
}
public void updateGraph() throws InterruptedException
{
// virtual x is how far along on the x axis we are, I ignore the 'real' X axis
int vx = 0;
int point = 0;
int xdecay = 0;
int inc = 5;
// how many times we need to plot a point
int points = (int) java.lang.Math.floor( width / inc );
System.out.println(points);
inner.preparePaint();
// draw all points to graph
// make some junk data, a saw like graph
for (vx = 0 ; vx < points ; vx++) {
series[vx] = new int[] { vx*inc, ( (vx*inc) % 120 ) };
}
Thread.sleep(150);
int n = 5;
while(n > 0) {
System.out.println(xdecay);
inner.preparePaint();
for (vx = 0 ; vx < points ; vx++) {
inner.updateSeries(vx, xdecay);
inner.repaint();
Thread.sleep(50);
}
xdecay += inc;
// shift the data points to the left
int[][] nseries = new int[points][2];
// System.arraycopy(series, 1, nseries, 0, points-1);
n--;
}
}
public class InnerGraph extends JPanel
{
private Graphics g;
private Image img;
private int gwidth;
private int gheight;
Dimension size;
public InnerGraph(int width, int height)
{
gwidth = width;
gheight = height;
size = new Dimension(1, 1);
}
/**
* Try make panel the requested size.
*/
public Dimension getPreferredSize()
{
return new Dimension(gwidth, gheight);
}
/**
* Create an image and graphics context
*
*/
public void preparePaint()
{
size = getSize();
img = inner.createImage( (size.width | gwidth), (size.height | gheight) );
g = img.getGraphics();
}
/**
* Draw a point to the chart given the point to use and the decay.
* Yes this is bad coding style until I work out the mathematics needed
* to do what I want.
*/
public void updateSeries(int point, int decay)
{
g.setColor(Color.blue);
int nx = series[point][0];
series[point][0] -= decay;
if ( point-1 >= 0 ) {
series[point-1][0] -= decay;
}
int ny = series[point][1];
prevx -= decay;
g.drawLine(prevx-decay, prevy, nx-decay, ny );
prevx = nx-decay;
prevy = ny;
}
public void paintComponent(Graphics g)
{
g.drawImage(img, 0, 0, null);
}
}
}
In the effort to learn more about applets and Java, I am experimenting making wave applets by drawing lines (drawLine) and making animated line graphs.
I can make a static graph just fine. However I am struggling with the animated aspect of the graph: the axes of the graph should move from left to right, increasing and growing larger than 0.
My problem is translating my needs into a solution. Can anyone give me any pointers with my problem?
I have a multidimensional array indexed by points containing the x and y of a particular point. I have tried modifying my render function to decrease the Xs to make it appear as if it is moving left but this doesn't work right.
What approach am I looking to take? How different will my approach be if the values of Y could change due to user action or added data?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
/**
* A graph that should in the future represent a wave according to my inputs
*
* @authorImprofane
* @version 1
*/
public class Graph extends JFrame
{
private InnerGraph inner;
private int width;
private Random RNG;
private int height;
private int[][] series;
private int xoffset;
int prevx = 0;
int prevy = 0;
/**
* Constructor for objects of class Graph
*/
public Graph(int width, int height) throws InterruptedException
{
RNG = new Random();
setTitle(" Graph");
series = new int[width][2];
this.width = width;
this.height = height;
inner = new InnerGraph(width, height);
add(inner, BorderLayout.CENTER);
setVisible(true);
inner.preparePaint();
pack();
updateGraph();
}
public static void main(String[] args) throws InterruptedException
{
new Graph(300, 300);
}
public void updateGraph() throws InterruptedException
{
// virtual x is how far along on the x axis we are, I ignore the 'real' X axis
int vx = 0;
int point = 0;
int xdecay = 0;
int inc = 5;
// how many times we need to plot a point
int points = (int) java.lang.Math.floor( width / inc );
System.out.println(points);
inner.preparePaint();
// draw all points to graph
// make some junk data, a saw like graph
for (vx = 0 ; vx < points ; vx++) {
series[vx] = new int[] { vx*inc, ( (vx*inc) % 120 ) };
}
Thread.sleep(150);
int n = 5;
while(n > 0) {
System.out.println(xdecay);
inner.preparePaint();
for (vx = 0 ; vx < points ; vx++) {
inner.updateSeries(vx, xdecay);
inner.repaint();
Thread.sleep(50);
}
xdecay += inc;
// shift the data points to the left
int[][] nseries = new int[points][2];
// System.arraycopy(series, 1, nseries, 0, points-1);
n--;
}
}
public class InnerGraph extends JPanel
{
private Graphics g;
private Image img;
private int gwidth;
private int gheight;
Dimension size;
public InnerGraph(int width, int height)
{
gwidth = width;
gheight = height;
size = new Dimension(1, 1);
}
/**
* Try make panel the requested size.
*/
public Dimension getPreferredSize()
{
return new Dimension(gwidth, gheight);
}
/**
* Create an image and graphics context
*
*/
public void preparePaint()
{
size = getSize();
img = inner.createImage( (size.width | gwidth), (size.height | gheight) );
g = img.getGraphics();
}
/**
* Draw a point to the chart given the point to use and the decay.
* Yes this is bad coding style until I work out the mathematics needed
* to do what I want.
*/
public void updateSeries(int point, int decay)
{
g.setColor(Color.blue);
int nx = series[point][0];
series[point][0] -= decay;
if ( point-1 >= 0 ) {
series[point-1][0] -= decay;
}
int ny = series[point][1];
prevx -= decay;
g.drawLine(prevx-decay, prevy, nx-decay, ny );
prevx = nx-decay;
prevy = ny;
}
public void paintComponent(Graphics g)
{
g.drawImage(img, 0, 0, null);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,看起来您在 updateSeries 方法中过于频繁地减去衰减。
以下是该方法的新版本。
通过这些更改,线条绘制得更好,但绘制速度太慢,以至于很难看清动画。您可能需要构建一个新图形并交换整个图形,这样您就不必观看绘制的每个单独的线段。
First, it looks like you are subtracting the decay too often in the updateSeries method.
Below is a new version of that method.
With those changes, the lines draw better, but they draw so slowly that the animation is hard to see. You probably need to build a new graphics and swap the whole thing so that you don't have to watch each individual line segment being drawn.
对于初学者,您可以查看以下示例(以及与此相关的示例)
滚动图表@java2s.com
For a starter you could check out the following example (and the ones related to this)
Scroll Chart @java2s.com