我使用双向链表来创建这个正在移动的正弦曲线(代码可能非常原始和混乱,但这只是初稿,我几乎不知道如何使用Swing ..):
import java.awt.*;
import javax.swing.JFrame;
public class DisplayGraphics extends Canvas{
public void paint(Graphics g) {
setForeground(Color.RED);
this.setSize(720,440);
class list {
int pos;
list next;
list prev;
list(){
int pos;
list next ;
list prev;
}
list(int pos){
this.pos = pos;
}
list(int pos, list next){
this.pos = pos;
this.next = next;
}
public void setpos(int pos){
this.pos= pos;
}
public void setnext(list next){
this.next= next;
next.prev=this;
}
public void display(list head){
list tracker = head;
int y;
//displays the sincurve momentarily
for (int i = 1;i<721; i++){
y = (int)(Math.sin(Math.toRadians(tracker.pos))*200)+200;
g.fillOval(i,y,3,3);
tracker = tracker.next;
}
}
}
list temp = new list();
temp.setpos(1);
list head = temp;
for (int i =2; i<720; i++){
list thing = new list();
thing.setpos(i);
temp.setnext(thing);
temp = thing;
}
list tail = new list(720);
temp.setnext(tail);
tail.setnext(head);
//creates the moving display
boolean run = true;
while(run==true){
head.display(head);
//try {
//Thread.sleep(10);
//} catch(InterruptedException ex) {
// Thread.currentThread().interrupt();
//}
g.clearRect(0, 0, getWidth(), getHeight());
head = head.next ;
}
}
public static void main(String[] args) {
DisplayGraphics m=new DisplayGraphics();
JFrame f=new JFrame();
f.add(m);
f.setSize(720,400);
//f.setLayout(null);
f.setVisible(true);
}
}
但是,该计划并不是非常顺利。是否有任何建议让它运行得更快,更顺畅?
答案 0 :(得分:4)
确定有一些必须纠正的缺陷^^
1)通过线程触发你的绘画
//set isRunning=false to stop repaint
private boolean isRunning = true;
private void startUpdateThread(){
Runnable r = new Runnable() {
public void run() {
while(isRunning){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
//repaint calls the paint(Graphics g)-method
repaint();
}
}
};
Thread t = new Thread(r);
t.setDaemon(true);
t.start();
}
2)不要让事情变得复杂:在绘画期间只计算f(x)= y ^^
3)只做油漆中的事情,必须做的事情:每次涂漆时都不要设置尺寸
private int xCount = 0;
public void paint(Graphics g) {
//setSize(...)
xCount = xCount + 1;
for (int dx = 1; dx < 721; dx++) {
int x = (xCount%721)+dx;
int y = (int) (Math.sin(Math.toRadians(x)) * 200) + 200;
g.fillOval(dx, y, 3, 3);
}
}
还剩下什么?你的设置^^
public static void main(String[] args) {
DisplayGraphic m = new DisplayGraphic();
m.startUpdateThread();
m.setSize(720, 440);
JFrame f = new JFrame();
f.add(m);
f.setSize(720, 400);
f.setVisible(true);
}
你可能想看一下缓冲...如果你不喜欢这样做,只需使用JPanel
而不是Canvas(你必须覆盖paintComponent(Graphics g)
而不是{ {1}})
paint(Graphics g)
答案 1 :(得分:4)
public class DisplayGraphics extends Canvas{
不要混合使用Swing和AWT。默认情况下,Swing组件(任何JComponent
)都是双缓冲的。这有助于避免生涩的渲染。
public void paint(Graphics g) {
setForeground(Color.RED);
每当我们覆盖任何paint方法时,我们应该立即调用super方法来擦除原始绘图。但是对于Swing,我们会覆盖paintComponent(Graphics)
而不是paint(Graphics)
。
设置前景色应该在构造函数中完成一次,然后单独保留。再次调用它会触发绘画!
this.setSize(720,440);
那是另一个会触发重画的东西!
此外,最好覆盖getPreferredSize()
方法和pack()
包含它的顶级窗口的大小。无论您使用哪种信息,网站,图书,都可以找到新的&amp;更好的版本。此代码显示了太多重要部分的不良做法。
是否有任何建议让它运行得更快,更顺畅?
使用Swing组件(例如JPanel
)代替Canvas
。做出改变&amp;覆盖上面提到的方法。创建一个在循环部分调用Timer
的Swing repaint()
。
见Performing Custom Painting&amp; How to Use Swing Timers以获得更好的学习资源。