删除MouseListener会产生ArrayIndexOutOfBoundsException

时间:2012-04-18 09:00:56

标签: java swing events exception mouselistener

我得到“线程中的异常”AWT-EventQueue-0“java.lang.ArrayIndexOutOfBoundsException:0 我真的不明白为什么。

我有两个内部类,我用作JPanel的监听器bildYta

private class NyPlatsLyss implements ActionListener{
    public void actionPerformed(ActionEvent e){
        bildYta.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
        bildYta.addMouseListener(new BildYtaLyss());
        bildYta.addKeyListener(new EscLyss());
        bildYta.requestFocusInWindow();
        enableOperations(false);
    }
}

private class EscLyss extends KeyAdapter{
    public void keyPressed(KeyEvent e){
        if(e.getKeyCode()==KeyEvent.VK_ESCAPE){
            bildYta.setCursor(Cursor.getDefaultCursor());
            bildYta.removeMouseListener(bildYta.getMouseListeners()[0]);
            bildYta.removeKeyListener(this);
            enableOperations(true);
        }
    }
}

当我按下按钮时,它会将两个听众添加到bildYta。我不明白的是为什么我得到.ArrayIndexOutOfBoundsException:0当我删除刚刚添加的鼠标监听器时。有时我甚至不会得到例外,有时我会这样做。我的其余代码中没有任何内容会导致任何问题,因为在我添加这些侦听器之后,我的程序中不会发生任何其他事情。它等待和ESC按下或鼠标单击

2 个答案:

答案 0 :(得分:2)

这是非常脆弱的代码。 EscLyss处理的事件可能会多次触发,并且只会在第一次触发时触发。在代码中添加一些检查。更好的是,将EscLyss实例保存到字段,然后直接删除该特定实例。更好的是,将该实例设为最终,然后您可以重复使用它,根据需要重复添加和删除它。事实上,这就是我们通常采用的方式。

private final MouseListener bildYtaLyss = new BildYtaLyss();

private class NyPlatsLyss implements ActionListener{
  public void actionPerformed(ActionEvent e) {
    bildYta.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
    bildYta.addMouseListener(bildYtaLyss);
    EscLyss escLyss = new EscLyss();
    bildYta.addKeyListener(escLyss);
    bildYta.requestFocusInWindow();
    enableOperations(false);
  }
}

private class EscLyss extends KeyAdapter{
  public void keyPressed(KeyEvent e){
    if(e.getKeyCode()==KeyEvent.VK_ESCAPE){
      bildYta.setCursor(Cursor.getDefaultCursor());
      bildYta.removeMouseListener(bildYtaLyss);
      bildYta.removeKeyListener(this);
      enableOperations(true);
    }
  }
}

答案 1 :(得分:1)

围绕SwingUtilities.invokeLater()

中的删除代码