当前位置: 首页 > 知识库问答 >
问题:

在GUI中移动对象何时需要计时器?

岑经纶
2023-03-14

我看到很多视频和教程在GUI中移动对象时使用计时器,但我尝试在没有计时器的情况下做一些事情,它似乎工作正常。我不太明白什么时候需要计时器。非常感谢任何帮助

没有计时器的两个移动对象的代码示例

import java.awt.Color;
import java.awt.Event;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;







public class Test2 extends JPanel{
    int x=100,y=200,velX=5,velY=5;
    int x2=300,y2=200;
    Action upAction;
    Action downAction;
    Action leftAction;
    Action rightAction;
    Action wAction;
    Action aAction;
    Action sAction;
    Action dAction;
    JLabel label3 = new JLabel();
    
    public Test2() {
        
        
        this.setLayout(null);
        this.setFocusable(true);
        this.setBackground(Color.LIGHT_GRAY);
        JLabel label1 = new JLabel("Press WASD to control Green Circle");
        label1.setBounds(40, 30, 250, 20);
        label1.setForeground(Color.GREEN);
        this.add(label1);
        JLabel label2 = new JLabel("Press Arrows to control Blue Circle");
        label2.setBounds(250, 30, 250, 20);
        label2.setForeground(Color.BLUE);
        this.add(label2);
        label3 = new JLabel("");
        label3.setBounds(200, 200, 250, 20);
        label3.setForeground(Color.RED);
        this.add(label3);
        upAction= new upAction();
        downAction= new downAction();
        leftAction = new leftAction();
        rightAction = new rightAction();
        wAction= new WAction();
        aAction = new AAction();
        sAction = new SAction();
        dAction= new DAction();
        
        
        
        
        
        this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("UP"), "uplol");;
        this.getActionMap().put("uplol", upAction);
        this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("DOWN"), "downlol");
        this.getActionMap().put("downlol", downAction);
        this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("LEFT"), "leftlol");
        this.getActionMap().put("leftlol", leftAction);
        this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("RIGHT"), "rightlol");
        this.getActionMap().put("rightlol", rightAction);

        this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('w'), "moveup");;
        this.getActionMap().put("moveup", wAction);
        this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('a'),"moveleft");
        this.getActionMap().put("moveleft", aAction);
        this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('s'), "movedown");
        this.getActionMap().put("movedown", sAction);
        this.getInputMap(WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('d'), "moveright");
        this.getActionMap().put("moveright", dAction);
    }
    
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(Color.GREEN);
        g.fillOval(x,y, 40, 40);
        g.setColor(Color.BLUE);
        g.fillOval(x2, y2, 40, 40);
        
    }


    
    public class upAction extends AbstractAction{

        @Override
        public void actionPerformed(ActionEvent e) {
            y-=velY;
            repaint();
            checkCollision();
            if(checkCollision()==true) {
                label3.setText("OVER");
                velY=0;
                velX=0;
                
                
            }
            
        }
        
    }

    public class downAction extends AbstractAction{

        @Override
        public void actionPerformed(ActionEvent e) {
            y+=velY;
            repaint();
            checkCollision();
            if(checkCollision()==true) {
                label3.setText("OVER");
                velY=0;
                velX=0;
                
            }
        }
    }
        

    public class rightAction extends AbstractAction{

        @Override
        public void actionPerformed(ActionEvent e) {
            x+=velX;
            repaint();
            checkCollision();
            if(checkCollision()==true) {
                label3.setText("OVER");
                velY=0;
                velX=0;
                
            }
            
        }
        
    }
    public class leftAction extends AbstractAction{

        @Override
        public void actionPerformed(ActionEvent e) {
            x-=velX;
            repaint();
            checkCollision();
            if(checkCollision()==true) {
                label3.setText("OVER");
                velY=0;
                velX=0;
                
            }
            
            
        }
        
    }

    
    public class WAction extends AbstractAction{

        @Override
        public void actionPerformed(ActionEvent e) {
            y2-=velY;
            repaint();
            checkCollision();
            if(checkCollision()==true) {
                label3.setText("OVER");
                velY=0;
                velX=0;
                
            }
            
        }
        
    }public class AAction extends AbstractAction{

        @Override
        public void actionPerformed(ActionEvent e) {
            x2-=velX;
            repaint();
            checkCollision();
            if(checkCollision()==true) {
                label3.setText("OVER");
                velY=0;
                velX=0;
                
            }
            
        }
        
    }public class DAction extends AbstractAction{

        @Override
        public void actionPerformed(ActionEvent e) {
            x2+=velY;
            repaint();
            checkCollision();
            if(checkCollision()==true) {
                label3.setText("OVER");
                velY=0;
                velX=0;
                
            }
            
            
        }
        
    }public class SAction extends AbstractAction{

        @Override
        public void actionPerformed(ActionEvent e) {
            y2+=velY;
            repaint();
            checkCollision();
            if(checkCollision()==true) {
                label3.setText("OVER");
                velY=0;
                velX=0;
                
            }
        }
        
    }
    public boolean checkCollision() {
        if((Math.pow(Math.abs(x2-x),2)+Math.pow(Math.abs(y2-y), 2))<=1600) {
            System.out.println("night");
            return true;
            
        }
        return false;
    }
    
        
    



}

带有计时器的代码示例

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Label;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import java.util.Timer;

import javax.swing.*;



public class Move extends JPanel implements ActionListener{
    javax.swing.Timer timer= new javax.swing.Timer(5, this);
    int y=0,x=0,velY=2,velX=2;
    
    
    
    
    @Override
    public void paint(Graphics g) {
        
        super.paint(g);
        
        this.setBackground(Color.MAGENTA);
        Graphics2D graphics2d = (Graphics2D)g;
        
        graphics2d.setColor(Color.BLUE);
        graphics2d.fill3DRect(100, 150, 100, 30, true);
        graphics2d.setColor(Color.RED);
        graphics2d.fillOval(200, 250, 28, 61);
        graphics2d.setColor(Color.BLACK);
        graphics2d.drawString("That boy is a monster", 80, 35);
        
        //timer.start();
    }
    public Move() {
        this.setLayout(null);
        JLabel rotter = new JLabel("fool");
        rotter.setBounds(140, 200, 53, 90);
        this.add(rotter);
        
        
        
    }


    @Override
    public void actionPerformed(ActionEvent e) {
        if(x<0||x>560) {
            velX=-velX;
        }
        if(y<0|y>360) {
            velY=-velY;
        }
        x+=velX;
        y+=velY;
        repaint();
        
        
    }


}

共有1个答案

李昊苍
2023-03-14

只要你只是

  • 直接对一个事件做出反应
  • 并且只更新一次显示

...没有计时器是完全可以的。

您可以/应该使用计时器的情况如下:

  • 如果你有一个正在进行的动画
  • 如果您没有直接对UI事件做出反应,但从另一个线程调用该事件的更改。

那为什么要用定时器呢?

  • Swing(您正在使用的)不是线程安全的,所以从EDT(事件调度线程)以外的线程更改一些UI元素可能会给您的UI带来混乱和混乱(非常奇怪的行为)。
  • 如果您有正在进行的动画-通常需要某种循环-在EDT中执行所有操作,UI将无法对任何输入做出反应,甚至无法正确更新自己。

所以你使用一个计时器,它会自动:

  • 在自己的线程中运行,所以UI不会阻塞
  • 并调用EDT更新UI以保持线程的安全和清洁
 类似资料:
  • 问题内容: 我有一个简单的应用程序,说它有一些类和一个“额外的”类来处理数据库请求。目前,每次使用该应用程序时,我都会创建数据库对象,但是在某些情况下,不需要数据库连接。我正在这样做(PHP btw): 但是有时对象不需要数据库访问,因为仅调用没有数据库操作的方法。所以我的问题是:处理这样的情况的专业方法是什么/如何仅在需要时才创建数据库连接/对象? 我的目标是避免不必要的数据库连接。 问题答案:

  • 问题内容: 所以,我不确定那是什么。如果在 ModuleA中 ,我有: 在 ModuleB中 ,我有: 在主程序中,我有: 因此,当我运行主程序时,我想我将创建两个猫鼬“实例”;一个连接到pathA,一个连接到pathB,对吗? 另外,在模块B中,在我连接到pathB之前,它是连接到pathA还是什么都没有? 谢谢。 问题答案: 我刚刚对最新的节点V0.4.6做了一些测试。我确认了以下内容: 从“

  • 问题内容: 令我惊讶的是,StackOverflow上没有人问过这个问题。 通过JSON对象文档和快速的Google搜索无法获得令人满意的结果。 有什么好处?它是如何工作的? 编辑:为了清楚起见,请看一下这个展平/未展平的示例。 谢谢。 问题答案: 在许多情况下,您会获得由某些库自动构建的JSON文本。在整个编程语言中,有许多库构建JSON文本(此处是一个示例 每当库添加一些其他对象或数组包装时,

  • 我试图使应用程序在反应本机(不是与博览会,我创建了我的代码与反应本机init和运行与反应本机run-android),当我在代码中做出改变,他们并不总是考虑到:考虑到他们我有重新启动计算机。 我一天要做几次,很费时。我已经测试过从设备上删除应用程序测试,以使Thread缓存干净,但它不起作用,唯一起作用的是重新启动(如果它起作用的话,我使用的是Mac)。 是否有一个命令可以让我重置我不知道的缓存并

  • 问题内容: 在创建iOS应用时,我确切地知道何时需要致电?我知道这与更新/重绘UI有关。但是,每次更改任何视图时,都需要调用此名称吗? 例如,我需要调用它吗: 以编程方式更改文本字段中的文本之后 更改视图背景时? 当我在viewDidLoad中进行更改时? 在viewDidAppear中怎么样? 有人可以给我一些有关何时使用此方法的一般指导吗? 问题答案: 如果您在UIView的子类中重写draw

  • 我正在为我的计算机科学课做一个项目,在这个项目中,我们使用pyplay在屏幕上移动一个物体。我不使用pygamesprites,而是导入到pygamesprites中的图像,并使用这些图像作为自定义sprites。当我试图在屏幕上移动兔子或“玩家”对象时,它似乎确实更新了位置。这是我试图改变位置的Player对象: 这是我用来运行游戏本身的类: