我刚开始学习Java编程,甚至最近学习图形,我遇到了一些问题。 我想创建一个像矮人堡垒一样的游戏,用彩色文字而不是图像。
这是我到目前为止所做的:
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.red);
for (int i = 0; i < 50; i++) {
g.drawString("[Game goes here]", 100, 150);
g.dispose();
System.out.println(i);
}
g.dispose();
}
public GTest() {
setSize(Toolkit.getDefaultToolkit().getScreenSize().width / 3, Toolkit
.getDefaultToolkit().getScreenSize().width / 3 + 50);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
GTest myWindow = new GTest();
}
我想让它更新计时器上的图形,但我不确定如何做到这一点。
我知道这是一个非常广泛的问题,我很乐意澄清你可能想知道的任何事情。
编辑:
所以我添加了这一点:
String[] letters = new String[10];
float fontsize = Toolkit.getDefaultToolkit().getScreenSize().width / 30;
public void paint(Graphics g) {
g.setColor(textColor);
setFont(getFont().deriveFont(fontsize));
for(int i = 0; i < 10; i++){
if((int) (Math.random() * 100) > 97){
letters[i] = "w";
textColor = new Color(0, 0, 100);
}else{
letters[i] = "l";
textColor = new Color(0, 100, 0);
}
g.drawString(letters[i], i * 3, 10);
}
但现在它根本不显示。我在g.drawString之后添加了一个sysout,它执行了它所以我不确定是什么问题。
答案 0 :(得分:2)
在Swing中根据计时器执行任何操作时,javax.swing.Timer
课程是您最好的朋友。
这是JavaDocs很好地解释了它的用法,所以这是一个例子。
public class GTest extends JFrame implements ActionListener {
private Color textColor = Color.BLACK;
private Random random = new Random();
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(textColor);
g.drawString("[Game goes here]", 100, 150);
}
@Override
public void actionPerformed(ActionEvent e) {
textColor = new Color(random.nextInt(0x00ffffff));
repaint();
}
public GTest() {
setSize(Toolkit.getDefaultToolkit().getScreenSize().width / 3,
Toolkit.getDefaultToolkit().getScreenSize().width / 3 + 50);
setDefaultCloseOperation(EXIT_ON_CLOSE);
Timer timer = new Timer(500, this);
timer.setInitialDelay(0);
timer.start();
setVisible(true);
}
public static void main(String[] args) {
GTest myWindow = new GTest();
}
}
这又是你的GTest
课程,但这次文字颜色每0.5秒自动更改一次。
请注意两个主要变化:
Timer
的新实例,没有初始延迟,周期为500毫秒,其侦听器设置为this
。这意味着这个构造的实例将监听该计时器的滴答声。ActionListener
接口。这迫使我们编写actionPerformed()
方法,每次定时器滴答时调用该方法。在此方法中,我们将textcolor更改为随机文本并调用repaint()
,然后调用我们的paint()
方法并获取文本。 P.S。您每次都不必dispose()
Graphics
个paint()
个对象。它实际上也在JavaDoc中说过(强调我的):
作为
update()
和dispose()
的参数提供的图形对象 组件的Graphics
方法由系统自动释放 当那些方法返回时。为了提高效率,程序员应该致电 仅在Graphics
对象创建完成后才使用{{1}} 直接来自组件或其他{{1}}对象。
答案 1 :(得分:2)
首先,如果您没有创建Graphics
上下文的副本,则不应该将其处理掉。这实际上可以防止您的申请表的其他部分被绘制;)
其次。我会避免从顶级容器延伸,比如JFrame
,除了允许你在窗口的框架/边框装饰下绘制,它们不是双缓冲的。
相反,我会使用类似JPanel
的内容,并覆盖其paintComponent
方法。这将为您提供自动双缓冲。
因为Swing是单线程框架,所以期望UI的所有更新都在Event Diapatching Thread的上下文中执行。
在尝试执行等待和同步绘制更新等操作时,这会让生活变得有点困难。
幸运的是,Swing提供了javax.swing.Timer
,允许您在将来的某个时间安排活动。这也可以设置为重复和定期间隔。
Timer timer = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent e) {
// perform your required actions here
}
});
现在,请注意,actionPerformed
方法正在使用EDT的上下文执行,这意味着,您在此处执行的任何长时间运行/耗时处理都可能导致UI停止绘制
看看
了解更多详情......