这些事情为什么会发生?

时间:2019-02-06 07:05:34

标签: java button timer awt timertask

[编辑]好的,感谢MalteKölle,'c'计算在删除之后就停止了。仍然存在“ c”未出版的问题,但我注意到了另一个问题。如果反复按下生成按钮,速度变量“ sw”和“ sh”会堆积,我不知道如何避免这种情况。我无法将速度变量设置为零,因为它在内部类中。我已经更新了代码。

我决定使用AWT在Java中创建一个简单的按钮游戏,该按钮的中心有一个按钮“ b”,它产生了另一个在屏幕上移动的按钮“ c”。单击“ c”时,将其删除。 'c'正常运行,但是我遇到两个问题。

  1. 通常单击“ c”会显示按下的动画,但此后仍然存在。我将如何使其在按下而不是按下时运行其actionListener?
  2. 单击并删除'c'时,即使它不存在,其运动的计算仍在运行。我不知道该如何解决。

额外。解决这些问题之后,下一步就是能够生成具有相同属性的多个按钮。如果有人有建议,将不胜感激。

我有很多系统输出可检测到此类问题,因此我知道它仍在计算。这是我的第一个代码项目,所以如果还有其他方法可以改进,请告诉我。 谢谢!

public class Main {

    Frame f = new Frame("Button Game");
    Button b = new Button("Spawn Button");
    Button c = new Button("Click Me!");

    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    int screenHeight = screenSize.height;
    int screenWidth = screenSize.width;
    int fh = f.getHeight();
    int fw = f.getWidth();
    boolean cExists;

    Main () {
        f.setSize(screenWidth/2,screenHeight/2); //Sets frame size
        f.setLocation(screenWidth/4,screenHeight/4); //Sets frame location
        f.setLayout(null); //Sets layout manager
        f.setVisible(true); //Sets frame to be visible
        System.out.println("Frame height:" + f.getHeight());
        System.out.println("Frame width:" + f.getWidth());
        fh = f.getHeight() + 20;
        fw = f.getWidth();

        f.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                super.windowClosing(e);
                System.out.println("Window closed by window listener");
                f.dispose();
                System.exit(1);
            }
        });

        f.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                super.componentResized(e);
                fw = f.getWidth();
                fh = f.getHeight();
                System.out.println("Frame size changed to " + f.getSize());
                b.setBounds(fw/2 - 60,fh/2 - 15, 120, 30);
                System.out.println("Button 'b' re-centered to " + b.getLocation());

                if (fw <= 320 || fh <= 180) {
                    f.setSize(320,180);
                }
            }
        });

        f.add(b);
        b.setBounds(fw/2 - 60,fh/2 - 15, 120, 30);
        System.out.println("Button 'f' spawned at " + b.getLocation());
        b.setVisible(true);

        b.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                int rn1 = ThreadLocalRandom.current().nextInt(30, fw - 130);
                int rn2 = ThreadLocalRandom.current().nextInt(50, fh - 60);
                f.add(c);
                cExists = true;
                c.setBounds(rn1, rn2, 100, 30);
                System.out.println("Button 'c' created at " + c.getLocation());

                int sh = ThreadLocalRandom.current().nextInt(-5, 10);
                int sw = ThreadLocalRandom.current().nextInt(-5, 10);
                System.out.println("Speed vertical: " + sh);
                System.out.println("Speed horizontal: " + sw);
                Timer timer = new Timer();
                class remindTask extends TimerTask {
                    public void run() {
                        if (cExists) {
                            c.setBounds(c.getX() + sw, c.getY() + sh, 100, 30);
                            System.out.println("Button 'c' moved to " + c.getLocation());
                            if (c.getX() >= fw-130) {
                                c.setBounds(30 + sw, c.getY() + sh, 100, 30);
                            } else if (c.getY() >= fh-60) {
                                c.setBounds(c.getX() + sw, 30 + sh, 100, 30);
                            } else if (c.getX() <= 30) {
                                c.setBounds(fw - 130 + sw, c.getY() + sh, 100, 30);
                            } else if (c.getY() <= 30) {
                                c.setBounds(c.getX() + sw, fh - 15 + sh, 100, 30);
                            }
                        } else {
                            timer.cancel();
                            //sw = 0; cant because it is inside an internal class. Maybe outsource to a method?
                            //sh = 0; Error:(94, 33) java: local variables referenced from an inner class must be final or effectively final
                        }
                    }
                }
                timer.schedule(new remindTask(), 0, 100);
            }
        });

        c.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                f.remove(c);
                cExists = false;
                System.out.println("'cExists' set to false");
                System.out.println("Removed button 'c' at " + c.getLocation());
            }
        });
    }

public static void main(String[] args) { //Calls code
    System.out.println("Code beginning"); //Logs beginning of runtime
    try { //Runs Main through run
        Main f = new Main();
        f.run(args);
    }
    catch (Exception e){ //NOT SURE
        e.printStackTrace();
    }
}

public void run (String[] args) throws Exception{ //New method to call non-static things
    System.out.println("Frame created");
}

1 个答案:

答案 0 :(得分:0)

您正在尝试检查cExists是否为True。但是要这样做,您将需要两个'=='而不是一个。

第77行:

public void run() {
  if (cExists == true) {
     c.setBounds(c.getX() + sw, c.getY() + sh, 100, 30);

检查布尔值是否为真的更简洁的方法可能是这样的:

if(cExists){

我在我的项目中尝试过,它对我有用。


编辑: 一个等号'='和两个等号'=='之间的区别:

一个等号是赋值运算。您正在使用它为变量分配值。
示例:

int number = 7

在这里,您将值7分配给变量“数字”

两个等号用于检查某些情况,例如:

if(number == 7){
   // do something
}

您要查找的是什么,因为它表示'如果数字等于7'。