【问题标题】:Stackoverflow error with ActionListenersActionListeners 的 Stackoverflow 错误
【发布时间】:2015-08-23 17:18:10
【问题描述】:

当我尝试用箭头键控制我的角色时,一切正常,但过了一会儿我得到了这个错误:

线程“AWT-EventQueue-0”java.lang.StackOverflowError 中的异常

然后

在 java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:249)

多次。我所拥有的课程甚至没有 249 行代码长,所以我不知道在哪里寻找问题。我的代码现在很乱,但如果它可以帮助任何人想出答案,我会发布它。

import javax.swing.JButton;
import javax.swing.JComponent;
import java.awt.Graphics;
import javax.swing.JFrame;
import java.awt.image.*;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

public class mainFrame extends JPanel implements Runnable, KeyListener {
    static boolean gameIsRunning = false;
    static final int TARGET_FPS = 1;
    static int x = 100;
    static int y = 100;
    static long startTime = 0;
    static long elapsedTime = 0;
    static long waitTime = 0;
    JFrame window = new JFrame("Out from Eden");
    JPanel panel = new JPanel();
    getResources get = new getResources();
    BufferedImage player = get.getImg("player");
    static int playerVal = 0;
    static int i = 0;
    static String currentState = "";
    static int lastFacing = 0;

    public void createFrame() {
        gameIsRunning = true;
        gameStart();
    }

    public void setGame(boolean game) {
        gameIsRunning = game;
    }

    public void gameStart() {
        (new Thread(new mainFrame())).start();
    }

    public void run() {
        while (gameIsRunning == true) {
            startTime = System.nanoTime();
            updateGame();
            renderGame();
            elapsedTime = System.nanoTime() - startTime;
            waitTime = (TARGET_FPS * 10) - (elapsedTime / 1000000);

            if (waitTime < 0) {
                waitTime = 5;
            }
            try {
                Thread.sleep(waitTime);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void updateGame() {
        if (x > 800) {
            x = 0;
        }

        if (currentState == "left") {
            x--;
        }
        if (currentState == "right") {
            x++;
        }
        player = royImage();

    }

    public BufferedImage royImage() {
        if (currentState == "right") {
            lastFacing = 2;
            i++;
            if (playerVal == 0) {
                playerVal = 1;
                i = 0;
                player = get.getImg("royWalk1");
            }
            if (playerVal == 1 && i > 20) {
                playerVal = 2;
                i = 0;
                return get.getImg("royWalk2");
            }
            if (playerVal == 2 && i > 20) {
                playerVal = 3;
                i = 0;
                player = get.getImg("royWalk3");
            }
            if (playerVal == 3 && i > 20) {
                playerVal = 4;
                i = 0;
                player = get.getImg("royWalk4");
            }
            if (playerVal == 4 && i > 20) {
                playerVal = 0;
                i = 0;
                player = get.getImg("royWalk1");
            }
        }

        if (currentState == "left") {
            lastFacing = 1;
            i++;
            if (playerVal == 0) {
                playerVal = 1;
                i = 0;
                player = get.getImg("royWalkL1");
            }
            if (playerVal == 1 && i > 20) {
                playerVal = 2;
                i = 0;
                player = get.getImg("royWalkL2");
            }
            if (playerVal == 2 && i > 20) {
                playerVal = 3;
                i = 0;
                player = get.getImg("royWalkL3");
            }
            if (playerVal == 3 && i > 20) {
                playerVal = 4;
                i = 0;
                player = get.getImg("royWalkL4");
            }
            if (playerVal == 4 && i > 20) {
                playerVal = 0;
                i = 0;
                player = get.getImg("royWalkL1");
            }
        }

        if (currentState == "null") {
            i = 0;
            playerVal = 0;
            if (lastFacing == 1) {
                player = get.getImg("playerL");
            }
            if (lastFacing == 2) {
                player = get.getImg("player");
            }
        }
        return player;
    }

    public void renderGame() {
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setBounds(30, 30, 700, 500);
        panel.setLayout(new BorderLayout());
        window.getContentPane().add(panel);
        panel.add(this);
        window.setFocusable(true);
        window.setFocusTraversalKeysEnabled(false);
        window.setVisible(true);
        window.addKeyListener(this);
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.drawString("Hello", x, y);
        g2.drawLine(0, 63, 700, 63);
        g2.drawImage(player, x - 100, y - 100, null);
    }

    public void keyTyped(KeyEvent e) {

    }

    public void keyPressed(KeyEvent e) {
        int code = e.getKeyCode();
        if (code == KeyEvent.VK_UP) {
            currentState = "up";
        }
        if (code == KeyEvent.VK_DOWN) {
            currentState = "down";
        }
        if (code == KeyEvent.VK_LEFT) {
            currentState = "left";
        }
        if (code == KeyEvent.VK_RIGHT) {
            currentState = "right";
        }
    }

    public void keyReleased(KeyEvent e) {
        currentState = "null";
    }
}

谁能帮我弄清楚为什么会出现堆栈溢出错误以及如何避免它?

【问题讨论】:

  • 请发布完整的堆栈跟踪。请指出哪一行代码有问题。您可能正在进行递归,您应该通过发布一个完整的问题来帮助我们找到它。
  • 堆栈跟踪只是“线程中的异常“AWT-EventQueue-0”java.lang.StackOverflowError”一次然后“在 java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:249)”重复了很多次。
  • 以后,将完整的堆栈跟踪与您的问题一样发布,而不是在评论中,因为它太重要了,不能隐藏在评论中。但现在并不重要,因为我知道你的问题——你在 while (true) 循环中重新添加 KeyListener——危险代码。您只想添加一次 KeyListener,实际上根本不想使用它,因为即使是 Oracle 也建议您避免使用它来支持 Key Bindings。
  • 另外请注意,您的问题与 ActionListeners 无关,与 StackOverflow 错误有关。

标签: java swing stack-overflow actionlistener arrow-keys


【解决方案1】:

当您在该循环中添加一个 KeyListener 无数次时,您的 while true 循环正在让您措手不及。不要那样做,尤其是你的renderGame() 方法。你为什么还要调用一个用于多次设置 GUI 的方法?调用该方法一次会更有意义。

另外,使用 Swing Timer(Google 教程)代替您的 while 循环,避免使用 KeyListeners 来支持 Key Binding(Google 教程,并查看 this example)并执行您的设置代码只有一次。

此外,当您在非后台线程中调用 Thread.sleep(...)while (true) 时,您的代码可能会导致 Swing 线程错误。为了安全起见,请改用 Swing Timer。

另外,您比较错误的字符串。不要使用==!= 比较字符串。请改用equals(...)equalsIgnoreCase(...) 方法。了解== 检查两个 对象引用 是否相同,这不是您感兴趣的。另一方面,这些方法检查两个字符串是否具有相同顺序的相同字符,这就是这里的重点。所以不是

if (fu == "bar") {
  // do something
}

做,

if ("bar".equals(fu)) {
  // do something
}

或者,

if ("bar".equalsIgnoreCase(fu)) {
  // do something
}

【讨论】:

    猜你喜欢
    • 2011-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 2011-12-19
    • 2011-12-26
    • 1970-01-01
    相关资源
    最近更新 更多