[英]Making a shape move back and forth using EventHandlers in Java
I think my title pretty well sums up my problem. 我认为我的头衔很好地概括了我的问题。 I'm really new to programming (about 2-3 weeks of self teaching using Head First Java) and I am trying to use Action Listener to make a square move back and forth on screen until the user terminates the program. 我真的是编程新手(使用Head First Java大约需要2-3个星期的自学时间),并且尝试使用Action Listener在屏幕上来回移动,直到用户终止程序为止。 My issue is that I have one Timer and 2 classes implementing Action Listener. 我的问题是我有一个Timer和2个实现Action Listener的类。 I can get it to run back and forth once, but that's all I can get it to do. 我可以让它来回运行一次,但这就是我所能做的。
package Animation;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Window extends JPanel implements ActionListener{
int x = 100;
Timer timer = new Timer(5, this);
int velX = 2;
public void paintComponent(Graphics g){
super.paintComponent(g);
this.setBackground(Color.BLACK);
g.setColor(Color.BLUE);
g.fill3DRect(x, 150, 200, 200, true);
timer.start();
if(x >= 1000){
timer.addActionListener(new HandlerClass());
}//end if
}//end paintComponent
public void actionPerformed(ActionEvent e){
x += velX;
repaint();
}//end actionP method
public class HandlerClass implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
if(x >= 100){
x -= velX;
repaint();
}
}//end actionP
}//end Handler
}//end Window
I've seen questions where people use buttons to move things back and forth or move things a set number of times, but I want the timer to do everything till the user exits. 我曾经看到过有人在哪里使用按钮来回移动或移动一定次数的问题,但是我希望计时器能够做所有事情直到用户退出。 That way the user only has to watch. 这样,用户仅需观看。 I Didn't include the class with my main method because that just sets up the gui and calls this class. 我没有在main方法中包含该类,因为这只是设置了gui并调用了该类。
First, take a look at Painting in AWT and Swing and Performing Custom Painting for more details about how painting works in Swing. 首先,查看AWT和Swing中的 绘画以及执行自定义绘画 ,以了解有关在Swing中绘画如何工作的更多详细信息。
Basically, Swing uses a passive rendering algorithm, this means that a paint cycle may occur at any time for any reason, most of the time without your direct intervention. 基本上,Swing使用被动渲染算法,这意味着在任何时候都可能由于任何原因在任何时候发生绘制周期,而在大多数情况下,无需您的直接干预即可。
You should never change the state of a component from within any paint method, paint methods should paint, that's it. 您绝对不能从任何绘制方法中更改组件的状态,绘制方法应该绘制,仅此而已。
There are a number of small problems, to start with, you are adding the Window
class AND the HandlerClass
as ActionListener
's to the Timer
, this means that you could potentially get into a position where these two listeners compete with each other over which way the object should move. 首先,存在许多小问题,您将Window
类和HandlerClass
作为ActionListener
添加到Timer
,这意味着您可能会处于这两个侦听器相互竞争的位置对象应该移动。 Better to place your movement logic into a single method, for example: 最好将移动逻辑放在单个方法中,例如:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Window extends JPanel {
int x = 100;
Timer timer = new Timer(5, new HandlerClass());
int velX = 2;
public Window() {
this.setBackground(Color.BLACK);
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fill3DRect(x, 150, 200, 200, true);
}//end paintComponent
public class HandlerClass implements ActionListener {
@Override
public void actionPerformed(ActionEvent e) {
x += velX;
if (x + 200 >= getWidth()) {
x = getWidth() - 200;
velX *= -1;
} else if (x < 0) {
x = 0;
velX *= -1;
}
repaint();
}//end actionP
}//end Handler
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new Window());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}//end Window
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.