【问题标题】:Java Swing: 'java.awt.AWTEventMulticaster.mouseMoved' errorJava Swing:“java.awt.AWTEventMulticaster.mouseMoved”错误
【发布时间】:2019-05-14 02:13:31
【问题描述】:

我一直在尝试创建一个“如果你能抓住我”游戏:当我启动它时,它会随机选择分配一个“点击我”按钮的位置。我不应该能够点击按钮,在我能够做到之前,文本应该被重新分配给另一个按钮。

它可以工作一段时间,但随后会引发以下错误:“java.awt.AWTEventMulticaster.mouseMoved”。

我一直在尝试使用 removeListener() 方法解决问题,但我似乎无法找到解决方案。有cmets吗?

这是我的代码:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.lang.*;

public class Game extends JFrame {
    //Panels
    private JPanel mainPanel = new JPanel();
    // Buttons
    private JButton[] buttons = new JButton[9];
    private JButton theChosenButton = new JButton();
    // other
    private int random = 0; 

    public Game() {
        this.setTitle("Catch me if you can");
        mainPanel.setLayout(new GridLayout(3, 3));

        // creates buttons
        for(int i = 0; i < 9 ; i++) {
            buttons[i] = new JButton();
            mainPanel.add(buttons[i]);
        }

        // Add everything to frame
        this.getContentPane().add(mainPanel);
        this.setSize(400, 400);
        this.setVisible(true);
    }

    // generates random number between 1 and 9 to be used 
    public int clickMeGenerator(){
        random = (int) Math.floor(Math.random() * 9);
        return random;
    }

    // randomly assigns clickMeGenerator to a button
    // add mouseMoved listener to the chosen button
    public void assign(){
        int randomButton = this.clickMeGenerator();
        theChosenButton = buttons[randomButton];
        theChosenButton.addMouseMotionListener(new MouseHover());
        theChosenButton.setText("Click me");    
    }
    public void removeListener() {
            theChosenButton.removeMouseMotionListener(new MouseHover());
        //}
    }

    // inner class
    class MouseHover implements MouseMotionListener {
        public void mouseMoved(MouseEvent e) {
            theChosenButton.setText("");
            Game.this.assign();

        }

        public void mouseDragged(MouseEvent e) {

        }
    }

} // end of class

测试类:

public class GameTest {
    public static void main (String args[]) {
        Game myGame = new Game();
        myGame.assign();
    }
}

非常感谢您的帮助!

【问题讨论】:

  • 建议:(1)使用MouseListenermouseEntered事件而不是MouseMotionListenermouseMoved。 (2) 在所有按钮上同时注册监听器。让它测试(在鼠标输入时)事件源是否是当前选择的按钮,在这种情况下只移动标签。 (3)修改你的assign()方法,确保它不会重新选择当前选择的按钮。
  • 作为一个单独但重要的事情,构建您的 GUI 并通过SwingUtilities.invokeAndWait() 在事件调度线程上执行初始按钮分配。 Swing 不是线程安全的。
  • 为了清楚起见,实际错误是Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError .. at java.desktop/java.awt.AWTEventMulticaster.mouseMoved(AWTEventMulticaster.java:337)

标签: java swing user-interface awt jbutton


【解决方案1】:

为了清楚起见,“实际”错误是...

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
    at java.desktop/java.awt.AWTEventMulticaster.mouseMoved(AWTEventMulticaster.java:337)
    at java.desktop/java.awt.AWTEventMulticaster.mouseMoved(AWTEventMulticaster.java:337)

所以查看代码...

  public void assign() {
    int randomButton = this.clickMeGenerator();
    theChosenButton = buttons[randomButton];
    theChosenButton.addMouseMotionListener(new MouseHover());
    theChosenButton.setText("Click me");
  }

你不断地向你的按钮添加一个新的MouseMotionListener,一遍又一遍,然后......

  public void removeListener() {
    theChosenButton.removeMouseMotionListener(new MouseHover());
    //}
  }

没有意义,因为您正试图从按钮中删除 MouseHover 的新实例,但它一开始就不会被应用。

我要做的第一件事是在Game 中创建一个MouseHover 的实例作为实例字段

 private MouseHover mouseHover = new MouseHover();

并在调用addMouseMotionListenerremoveMouseMotionListener 时使用它。

然后,我会从“当前”活动按钮中删除侦听器,然后再将其添加到下一个按钮。

就个人而言,我会在assign 方法中这样做

public void assign() {
  int randomButton = this.clickMeGenerator();
  if (theChosenButton != null) {
    theChosenButton.removeMouseMotionListener(mouseHover);
  }
  theChosenButton = buttons[randomButton];
  theChosenButton.addMouseMotionListener(mouseHover);
  theChosenButton.setText("Click me");
}

我还会确保在第一次创建类时从事件调度线程中调用assign,因为 UI 已经在Game 的构造函数结束时实现,这意味着第一次调用@987654335 @ 在 EDT 的上下文之外,不建议这样做。

public static void main(String args[]) {
  EventQueue.invokeLater(new Runnable() {
    @Override
    public void run() {
      Game myGame = new Game();
      myGame.assign();
    }
  });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-09
    • 2012-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    相关资源
    最近更新 更多