当前位置: 首页 > 面试题库 >

延迟循环使JFrame无法响应

辛意智
2023-03-14
问题内容

因此,当我运行此代码时,我的JFrame变得无响应。我设法将其追溯到gameLoop()下的while循环。无论使用其中调用Thread.sleep()的delay(1000
/ FRAMERATE),它都不允许键或鼠标侦听器执行其工作。

下面的完整代码,gameLoop()中存在问题

package me.LemmingsGame;

import java.awt.*;
import java.awt.event.*;
import java.io.*;

import javax.swing.*;

public class Game extends JFrame implements KeyListener, MouseListener{

    private World wrld;//reference to current world
    private WorldFile loader=null;//world data

    private int gateCounter;

    private int width,height; //width and height of level

    private int mx,my;

    private int tool = Lemming.CLIMB;
    private Image dbImage; private Graphics dbg; //backbuffer  
    private Image [] sprites;//all images used in game

    private Lemming[] lemmings; //array of all Lemmings in level
    private int nextLem;//next Lemming to be received from Gate class

    private int running;//state of game
    private static final int FRAMERATE=180;//assigned framerate

    public Game(WorldFile loader){
        super("Lemmings");
        setLocation(50,40);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        width=3+loader.x*10;height=29+loader.y*10;
        loadImages();
        lemmings=new Lemming[loader.noLemmings*loader.gates().length];
        setSize(width,height);
        setVisible(true);   
        addMouseListener(this);
        addKeyListener(this);
        this.loader=loader;
        running=2;
        dbImage= createImage(width,height);
        dbg=dbImage.getGraphics();
        wrld=new World(loader,createImage(width,height), sprites, this);
        gameLoop();
    }
    public void loadImages(){
        sprites=new Image[2];
        sprites[0]=new ImageIcon("Resources/toolbar.png").getImage();
        sprites[1]=new ImageIcon("Resources/selector.png").getImage();
    }
    public static void delay(long len){
        try{
            Thread.sleep(len);
        }catch(InterruptedException e){
            System.out.println(e);
        }
    }
    public void moveLemmings(){
        if(nextLem>0)
            for(int i = 0;i<nextLem;i++)
                lemmings[i].cycle();
    }
    public void gameLoop(){

        wrld.openGates();
        while(running>0){
            delay(1000/FRAMERATE);
            if(running==2){
                gateCounter++;
                if(gateCounter>FRAMERATE*2){
                    wrld.cycleGates();
                    gateCounter=0;
                }
                moveLemmings();
                if(nextLem>0)
                    wrld.checkPositions(lemmings,nextLem);
            }
            repaint();
            //paint(getGraphics());
        }
    }
    public void paint(Graphics g){
        if(wrld!=null){
            dbg.setColor(Color.BLACK);
            dbg.fillRect(0, 0, width, height);
            wrld.draw(dbg);
            if(nextLem>0)
                for(int i=0;i<nextLem;i++){
                    lemmings[i].draw(dbg);
                }
            dbg.drawImage(sprites[0],0,0,null);
            dbg.drawImage(sprites[1],tool-3*39,0,null);
            g.drawImage(dbImage,3,29,this);
        }
    }
    public void addLemming(Lemming lemmy) {
        lemmings[nextLem]=lemmy;
        lemmy.spawn();
        nextLem++;
    }
    public void goal(){
        running=0;
        dispose();
        new Menu();
    }
    public void fail(){
        running=0;
        dispose();
        new Menu();
    }
    public void mouseClicked(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) {}
    public void mouseExited(MouseEvent e) {}
    public void keyTyped(KeyEvent e) {}
    public void mousePressed(MouseEvent e) {
        System.out.println("boop");
        mx=e.getX();
        my=e.getY();
        if(my<40)
            if(mx<40)
                tool=Lemming.CLIMB;
            else if(mx>39&&mx<=39*2)
                tool=Lemming.CHUTE;

    }
    public void mouseReleased(MouseEvent arg0) {
        // TODO Auto-generated method stub

    }
    public void keyPressed(KeyEvent e) {
        System.out.println("boop2");
    }

    public void keyReleased(KeyEvent e) {

    }
}

如果很重要,程序将从此处开始,然后转到Game类

package me.LemmingsGame;

import java.awt.*;
import java.awt.event.*;
import java.io.File;

import javax.swing.*;

public class Menu extends JFrame implements ActionListener{
    /**
     * 
     */
    private static final long serialVersionUID = -1448646591011984524L;
    private JComboBox worldList;
    private JButton launch, worldEditor;
    private String [] worldPaths;
    private String [] worldNames;
    private int currentWorld;
    public Menu(){
        super("Lemmings! By: Jordan and Seth");
        this.setLocation(new Point(550,400));
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        File listDir[] = new File("./Worlds").listFiles();
        int x=0;
        for (int i = 0; i < listDir.length; i++) 
            if (listDir[i].isDirectory()) 
                   x++;
        worldPaths=new String[x];
        worldNames=new String[x];
        x=0;
        for (int i = 0; i < listDir.length; i++) 
            if (listDir[i].isDirectory()){ 
                    worldPaths[x]=listDir[i].getPath().substring(2);    
                    worldNames[x]=worldPaths[x].substring(7);
                    x++;
            }
        worldList=new JComboBox(worldNames);
        worldList.addActionListener(this);
        worldEditor=new JButton("Open World Editor");
        worldEditor.addActionListener(this);
        launch = new JButton("Play");
        launch.addActionListener(this);
        Container cp = getContentPane();
        cp.setLayout(new FlowLayout());
        cp.add(worldEditor);
        cp.add(worldList);
        cp.add(launch);
        pack();
        setVisible(true);
    }
    public void actionPerformed(ActionEvent e){
        if(e.getSource()==worldEditor){
            dispose();
            new MapEditor();
        }else if(e.getSource()==launch){
            dispose();
            try {
                new Game(new WorldFile(worldPaths[currentWorld]));
            } catch (Exception e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }else if(e.getSource()==worldList){
            currentWorld=worldList.getSelectedIndex();
        }
    }
    public static void main(String [] args){
        new Menu();
    }
}

可能无关紧要,但这是github存储库的插件https://github.com/cybnetsurfe3011/Lemmings-Computer-
Science/


问题答案:

您正在执行Thread.sleep()您的主线程,在这种情况下,即EDT(事件调度程序线程)。该线程负责绘制图形并收听事件。通过这样做,Thread.sleep()您实际上是在暂停它,因此不允许它完成任务。

看来您想每隔一段时间刷新一次GUI(至少这是我所猜测的)。如果是这种情况,则需要将逻辑移至新的单独线程,然后从产生的线程中调用所需的更新方法。若要使更改可见,您将需要使用SwingUtilities.invokeLater()方法再次调用事件调度程序线程。



 类似资料:
  • 我在试着理解为什么一些简单的环路会以这样的速度运行 第一种情况: 根据IACA,吞吐量是1个周期,瓶颈是端口1,05。我不明白为什么它是1 cylce。毕竟我们有两个循环承载的依赖关系: 而且这种Latency是循环进行的,所以它应该会减慢我们的迭代。 第二种情况: 我更不明白为什么吞吐量是1.65。

  • 如何在不停止主GUI线程的情况下停止循环?(线程。睡眠(1000)未工作)

  • 问题内容: 如何在JavaScript中进行无限循环?我正在尝试制作幻灯片,可以正常工作,但是无法循环播放。我什至不能让它循环两次。 我现在正在使用的代码是 没有for的东西在那里,它确实经历了一次。当我输入for时,它要么使Firefox锁定,要么仅循环一次。我确信这是一件非常简单的事情,即使必须循环1,000,000次或进行其他操作(而不是无限循环),这对我来说也很好。 另外,我不想使用jQu

  • 问题内容: 我正在使用带有node_redis的Node.js,并遍历一个对象并在Redis中查找数据,然后返回结果。 我有这样的设置: 问题在于,它会在完成对redis的调用之前循环通过。因此,在实际更新总值之前,将调用回调。由于延迟,它似乎也跳过了一些项目。 有没有更好的方法来解决这个问题? 谢谢! 编辑: 好的,所以我这样更新了它: 这似乎可行,它在适当的时间触发了回调,但是似乎只有最后一个

  • 问题内容: 我想在循环内添加延迟/睡眠: 我这样尝试过: 只有第一种情况是正确的:显示后,它将等待3秒钟,然后显示,但随后将不断重复。 我想要的是在显示3秒之后显示出来,然后它需要第二次等待3秒,依此类推。 问题答案: 该函数是非阻塞的,将立即返回。因此,您的循环将非常快速地迭代,并且将快速连续地发起3秒超时触发。这就是为什么您的第一个警报会在3秒钟后弹出,而其余所有警报都将连续不断地出现。 您可

  • 我试图将SDL程序限制为60 FPS,并使用以下代码计算FPS: 但似乎SDL_Delay以某种方式影响了SDL_GetTicks的返回值,因此time_delta得到的值类似于0到3,而当我只删除最后2行时,它通常约为15。 对我来说,这毫无意义。有人知道怎么回事吗? 编辑: 上面的代码基本上是我程序的主循环。我首先实现了一个fps计数器,通过在start_time和afterwords中计算多