keyReleased上的StackOverflowError,但mouseReleased工作正常

时间:2013-03-31 05:22:36

标签: java swing stack-overflow keylistener

使用鼠标进行选择可以正常工作,如下面的运行时日志所示:

init:
Deleting: /home/thufir/NetBeansProjects/gnumail-providers/build/built-jar.properties
deps-jar:
Updating property file: /home/thufir/NetBeansProjects/gnumail-providers/build/built-jar.properties
compile:
run:
Mar 30, 2013 10:16:36 PM net.bounceme.dur.nntp.swing.ArticlesPanel itemSelected
INFO: selected      item        8
Mar 30, 2013 10:16:39 PM net.bounceme.dur.nntp.swing.ArticlesPanel itemSelected
INFO: selected      item        1
Mar 30, 2013 10:16:41 PM net.bounceme.dur.nntp.swing.ArticlesPanel itemSelected
INFO: selected      item        5
Mar 30, 2013 10:16:42 PM net.bounceme.dur.nntp.swing.ArticlesPanel itemSelected
INFO: selected      item        3
Mar 30, 2013 10:16:44 PM net.bounceme.dur.nntp.swing.ArticlesPanel itemSelected
INFO: selected      item        7
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
    at net.bounceme.dur.nntp.swing.ArticlesPanel$2.keyReleased(ArticlesPanel.java:49)
    at net.bounceme.dur.nntp.swing.ArticlesPanel$2.keyReleased(ArticlesPanel.java:49)
    at net.bounceme.dur.nntp.swing.ArticlesPanel$2.keyReleased(ArticlesPanel.java:49)
    at net.bounceme.dur.nntp.swing.ArticlesPanel$2.keyReleased(ArticlesPanel.java:49)
    at net.bounceme.dur.nntp.swing.ArticlesPanel$2.keyReleased(ArticlesPanel.java:49)

但是,当键和鼠标选择执行(或应该)调用相同的方法时,为什么使用键盘箭头选择会导致StackOverflowErroritemSelected

相关课程:

package net.bounceme.dur.nntp.swing;

import gnu.mail.providers.nntp.GroupMetaData;
import java.util.List;
import java.util.logging.Logger;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import net.bounceme.dur.nntp.gnu.PMD;
import net.bounceme.dur.nntp.gnu.Page;
import net.bounceme.dur.nntp.gnu.Usenet;

public class ArticlesPanel extends JPanel {

    private static final Logger LOG = Logger.getLogger(ArticlesPanel.class.getName());
    private static final long serialVersionUID = 1L;
    private JList<String> jList = new JList<>();
    private JScrollPane scrollPane = new JScrollPane();
    private DefaultListModel<String> dlm;

    public ArticlesPanel() throws MessagingException {

        initComponents();
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {
        setLayout(new java.awt.BorderLayout());

        dlm = new DefaultListModel<>();
        for (int i = 1; i < 9; i++) {
            dlm.addElement("item\t\t" + i);
        }

        jList.setModel(dlm);
        jList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        jList.addMouseListener(new java.awt.event.MouseAdapter() {

            public void mouseReleased(java.awt.event.MouseEvent evt) {
                mouseReleases(evt);
            }
        });
        jList.addKeyListener(new java.awt.event.KeyAdapter() {

            public void keyReleased(java.awt.event.KeyEvent evt) {
                keyReleased(evt);
            }
        });

        scrollPane.setViewportView(jList);
        add(scrollPane, java.awt.BorderLayout.CENTER);

        this.setSize(300, 100);
        this.setVisible(true);
    }

    private void keyReleased(java.awt.event.KeyEvent evt) {
        itemSelected();
    }

    private void mouseReleases(java.awt.event.MouseEvent evt) {
        itemSelected();
    }

    private void itemSelected() {
        LOG.info("selected\t\t" + jList.getSelectedValue());
    }
}

和调用类:

package net.bounceme.dur.nntp.swing;

import java.util.logging.Logger;
import javax.mail.MessagingException;
import javax.swing.*;
import java.awt.*;

public class Driver {

    private static final Logger LOG = Logger.getLogger(Driver.class.getName());

    private static void createAndShowGUI() throws MessagingException  {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(true);
        GraphicsEnvironment e = GraphicsEnvironment.getLocalGraphicsEnvironment();
        frame.setMaximizedBounds(e.getMaximumWindowBounds());
        frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
        frame.setLayout(new BorderLayout());

        JTabbedPane tabs = new JTabbedPane();

        ArticlesPanel myPanel = new ArticlesPanel();
        tabs.add(myPanel);
        frame.add(tabs);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String... args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                try {
                    createAndShowGUI();
                } catch (MessagingException ex) {
                    LOG.warning(ex.getLocalizedMessage());
                }
            }
        });
    }
}

1 个答案:

答案 0 :(得分:4)

StackOverflowError来电时收到keyReleased(evt),因为KeyAdapter中的方法会隐藏ArticlesPanel中的方法。结果是无限递归:

public void keyReleased(java.awt.event.KeyEvent evt) {
    keyReleased(evt); // calling this same method again
}

这在mouseReleased来电中不会发生,因为您自己的方法被称为mouseReleases(请注意s)。

public void mouseReleased(java.awt.event.MouseEvent evt) {
    mouseReleases(evt); // calling the method in the outer class
}