简体   繁体   English

使用Java中的EventHandlers使形状来回移动

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM