【发布时间】:2019-02-10 18:17:55
【问题描述】:
我正在尝试制作一个非常基本的动画,其中来自 ArrayList 的单词在屏幕上移动。为此,我使用了 drawString() 方法和一个计时器,以每隔设定的毫秒数更改 x 位置。我的paintComponent 方法当前设置为绘制两个不同的单词,首先是单词“Hello”,然后是2.5 秒后的单词“World”。
我的问题是图形坐标系似乎在移动,因此,我在第一个“Hello”之后生成的单词表现不同。单词“World”设置为常数 x = 0,但它会在屏幕中间生成,并且会随着单词“Hello”移动。此外,粉色背景本身的移动速度似乎与文字不同!
最让我难过的是,如果我去掉第 32-38 行(产生单词的代码),只设置背景颜色,背景仍然会移动。但是,如果我去掉第 80 行(改变 x 的方法),背景就会停止移动。这意味着我的 x 值和背景之间肯定有关系,但我就是不知道它是什么。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Word extends JPanel{
private ArrayList<String> phrase;
int x;
private int y;
private int interval;
private Word(ArrayList<String> Phrase,int height,int Interval){
interval = Interval;
y = height;
phrase = Phrase;
this.setBackground(Color.WHITE);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
this.setBackground(Color.MAGENTA);
g.setColor(Color.BLACK);
g.setFont(new Font("TimesRoman", Font.BOLD, 30));
for (int num = 0; num < phrase.size(); num++){
if(num == 2){
g.drawString(phrase.get(num), 0, 100*(num+1));
}else{
g.drawString(phrase.get(num), x, 100*(num + 1));
}
}
}
public void changeX(){
x += 1;
}
public ArrayList<String> getPhrase(){
return phrase;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public int getInterval(){
return interval;
}
public static void main(String[] args){
final ArrayList<String> words = new ArrayList<String>();
words.add("Hello");
// words.add("World");
final Word test = new Word(words, 100, 50);
final JFrame frame = new JFrame("test");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setBackground(Color.WHITE);
frame.add(test);
frame.setVisible(true);
Timer testTimer = new Timer();
TimerTask testTask = new TimerTask(){
int counter = 0;
boolean spawned = false;
public void run(){
test.changeX();
frame.repaint();
System.out.println(counter);
if(counter>50 && !spawned){
words.add("World");
spawned = true;
}
counter++;
}
};
testTimer.scheduleAtFixedRate(testTask, 0, test.getInterval());
}
}
我预计“世界”这个词会出现在画面的最左侧并保持静止。
【问题讨论】:
-
Swing 不是线程安全的,你不应该从事件调度线程的上下文之外更新 UI(或 UI 所依赖的东西)
标签: java swing graphics paintcomponent