java获取堆栈溢出程序不是递归的

时间:2017-08-19 22:22:03

标签: java swing recursion stack-overflow

我一直在研究我的“随机琐事”程序,我一直在堆栈溢出,没有递归,至少我找不到任何,这里是Gui.java的代码,主类(只有类)

package mods.giantnuker.random_trivia;

import java.awt.event.ActionEvent;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactoryConfigurationError;

import mods.giantnuker.javautil.FileFilterAccessor;
import mods.giantnuker.javautil.Pair;
import mods.giantnuker.javautil.PairList;
import mods.giantnuker.javautil.file.parser.XMLParser;

import javax.swing.JFileChooser;

@SuppressWarnings("serial")
public class Gui extends JFrame implements ActionListener, ItemListener {
    String tsn;
    JFileChooser dialg;
    JPanel welcome, newt;
    JButton sbttn, nbttn, ebttn, nqb, nab, dqb, dab, sav, ext;
    @SuppressWarnings("rawtypes")
    JComboBox questions, answers;
    List<Pair<String, PairList<String, Integer>>> trivia;
    public static void main(String[] args) {
        new Gui();
    }
    @SuppressWarnings({ "static-access", "rawtypes" })
    public Gui() {
        super("Random Trivia");
        this.setSize(300, 250);
        this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
        //New
        newt = new JPanel();
        newt.setLayout(new BoxLayout(newt, BoxLayout.Y_AXIS));
        questions = new JComboBox();
        questions.addItemListener(this);
        answers = new JComboBox();
        nqb = new JButton("New Question+   ");
        nab = new JButton("New Answer+     ");
        dqb = new JButton("-Delete Question");
        dab = new JButton("-Delete Answer  ");
        sav = new JButton("*Save                    ");
        ext = new JButton("-Exit-                     ");
        nqb.addActionListener(this);
        nab.addActionListener(this);
        dqb.addActionListener(this);
        dab.addActionListener(this);
        sav.addActionListener(this);
        ext.addActionListener(this);
        newt.add(questions);
        newt.add(answers);
        newt.add(nqb);
        newt.add(nab);
        newt.add(dqb);
        newt.add(dab);
        newt.add(sav);
        newt.add(ext);
        //Welcome
        welcome = new JPanel();
        welcome.setLayout(new BoxLayout(welcome, BoxLayout.Y_AXIS));
        welcome.add(new JLabel("Welcome To Random Trivia!"));
        welcome.add(sbttn = new JButton("Select a file(.trv) to use"));
        welcome.add(nbttn = new JButton("Create a new one"));
        welcome.add(ebttn = new JButton("Or edit an old one"));
        sbttn.addActionListener(this);
        nbttn.addActionListener(this);
        ebttn.addActionListener(this);
        dialg = new JFileChooser();
        dialg.setDialogType(dialg.OPEN_DIALOG);
        dialg.setFileFilter(new FileFilterAccessor("trv"));
        this.add(welcome);
        this.setVisible(true);
    }
    @SuppressWarnings({ "unchecked", "rawtypes", "static-access" })
    @Override
    public void actionPerformed(ActionEvent arg0) {
        Object src = arg0.getSource();
        if (src == sbttn) {
            dialg.setDialogType(dialg.OPEN_DIALOG);
            List<Map<String, Integer>> trivia = new ArrayList();
            int out = dialg.showOpenDialog(null);
            if(out == 0) {
                File f = dialg.getSelectedFile();
            }
        }
        if (src == nbttn) {
            trivia = new ArrayList();
            this.remove(welcome);
            this.add(newt);
            this.setVisible(true);
        }
        if (src == ebttn) {
            dialg.setDialogType(dialg.OPEN_DIALOG);
            int out = dialg.showOpenDialog(null);
            if(out == 0) {
                trivia = parse(dialg.getSelectedFile());
                this.remove(welcome);
                this.add(newt);
                ref();
                this.setVisible(true);
            }
        }
        if (src == ext) {
            this.remove(newt);
            this.add(welcome);
            this.setVisible(true);
        }
        if (src == nqb) {
            String txt = JOptionPane.showInputDialog(this ,"Enter the Question:", "Question...");
            if (txt.length() > 0 && !txt.equals("Question...")) {
                trivia.add(new Pair(txt, new PairList()));
                questions.addItem(txt);
            }
        }
        if (src == nab) {
            if (questions.getItemCount() == 0) {
                JOptionPane.showMessageDialog(this, "You must select a question or create one!", "Error", JOptionPane.WARNING_MESSAGE);
                return;
            }
            String txt = JOptionPane.showInputDialog(this ,"Enter the Answer:", "Answer...");
            String txt2 = JOptionPane.showInputDialog(this ,"Enter the amount of points for the Answer:", "Points...");
            if (txt.length() > 0 && !txt.equals("Answer...")) {
                if (txt2.length() > 0 && !txt2.equals("Points...")) {
                    int points = 0;
                    boolean err = true;
                    while(err) {
                        try {
                            points = Integer.valueOf(txt2);
                            err = false;
                        } catch (NumberFormatException e) {
                            txt2 = JOptionPane.showInputDialog(this ,"Enter the amount of points for the Answer:", "Points...");
                            if (txt2.equals("Points...")) return;
                        }
                    }
                    trivia.get(questions.getSelectedIndex()).getB().add(txt, points);
                    answers.addItem(txt + "(" + points + " points)");
                }
            }
        }
        if (src == dab) {
            if (questions.getItemCount() == 0) {
                JOptionPane.showMessageDialog(this, "You must select a question!", "Error", JOptionPane.WARNING_MESSAGE);
                return;
            }
            if (answers.getItemCount() != 0) {
                trivia.get(questions.getSelectedIndex()).getB().remove(answers.getSelectedIndex());
                answers.removeItemAt(answers.getSelectedIndex());
            }
        }
        if (src == dqb) {
            if (questions.getItemCount() != 0) {
                trivia.remove(trivia.get(questions.getSelectedIndex()));
                questions.removeItemAt(questions.getSelectedIndex());
                ref();
            }
        }
        if (src == sav) {
            tsn = JOptionPane.showInputDialog(this ,"Enter the name of the Trivia:", "Name...");
            if (!tsn.equals("Name...")) newTriviaSave();
        }
    }

    @SuppressWarnings("static-access")
    public void newTriviaSave() {
        dialg.setDialogType(dialg.SAVE_DIALOG);
        int out = dialg.showSaveDialog(null);
        if(out == 0) {
            File f = dialg.getSelectedFile();
            if (!f.getPath().contains(".")) {
                f = new File(f.getPath() + ".trv");
            }
            System.out.println(f.getPath());
            toFile(f, trivia, tsn);
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public List<Pair<String, PairList<String, Integer>>> parse(File f) {
        List<Pair<String, PairList<String, Integer>>> trivia = new ArrayList();
        XMLParser p = new XMLParser(f);
        try {
            p.read();
            p.doc.getDocumentElement().normalize();
            NodeList l = p.doc.getElementsByTagName("trivia");
            Element root = (Element) l.item(0);
            tsn = root.getAttribute("name");
            l = root.getElementsByTagName("question");
            for (int i = 0; i < l.getLength(); i++) {
                Element question = (Element)l.item(i);
                NodeList l2 = question.getElementsByTagName("answer");
                PairList<String, Integer> answers = new PairList();
                for (int j = 0; j < l2.getLength(); j++) {
                    Element answer = (Element)l2.item(j);
                    answers.add(answer.getAttribute("text"), Integer.valueOf(answer.getAttribute("points")));
                }
                trivia.add(new Pair(question.getAttribute("text"), answers));
            }
        } catch (Exception e) {

        }
        return trivia;
    }

    public void toFile(File f, List<Pair<String, PairList<String, Integer>>> questions, String name) {
        XMLParser p = new XMLParser(f);
        try {
            p.create();
            Element root = p.doc.createElement("trivia");
            root.setAttribute("name", name);
            for (Pair<String, PairList<String, Integer>> question : questions) {
                Element questionE = p.doc.createElement("question");
                questionE.setAttribute("text", question.getA());
                for (Pair<String, Integer> answer : question.getB()) {
                    Element answerE = p.doc.createElement("answer");
                    answerE.setAttribute("text", answer.getA());
                    answerE.setAttribute("points", String.valueOf(answer.getB()));
                    questionE.appendChild(answerE);
                }
                root.appendChild(questionE);
            }
            p.doc.appendChild(root);
            p.write();
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TransformerFactoryConfigurationError e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    @Override
    public void itemStateChanged(ItemEvent arg0) {
        Object src = arg0.getSource();
        if (src == questions) {
            ref();
        }
    }

    @SuppressWarnings("unchecked")
    public void ref() {
        questions.removeAllItems();
        answers.removeAllItems();
        for (Pair<String, PairList<String, Integer>> p : trivia) {
            questions.addItem(p.getA());
        }
        if (questions.getItemCount() != 0) {
            PairList<String, Integer> answes = trivia.get(questions.getSelectedIndex()).getB();
            for (Pair<String, Integer> ans : answes) {
                answers.addItem(ans.getA() + "(" + ans.getB() + " points)");
            }
        }
    }
}

JavaUtil工作正常 - 与它无关。

Here是一个带有JavaUtil预打包的可运行jar。 得到我的错误,点击“编辑旧的”并打开以下文件(只是一个虚拟文件,你可以自己制作并得到相同的结果)

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<trivia name="Dummy Trivia">
    <question text="dum">
        <answer points="1" text="ans1"/>
    </question><question text="dum2">
        <answer points="1" text="ans1"/>
        <answer points="2" text="ans2"/>
    </question>
    <question text="dum3">
        <answer points="1" text="ans1"/>
        <answer points="2" text="ans2"/>
        <answer points="3" text="ans3"/>
    </question>
</trivia>

谢谢:)

编辑:堆栈溢出在ref()\代表刷新

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
    at javax.swing.plaf.basic.BasicComboBoxUI$Handler.contentsChanged(BasicComboBoxUI.java:1858)
    at javax.swing.plaf.basic.BasicComboBoxUI$Handler.intervalRemoved(BasicComboBoxUI.java:1877)
    at javax.swing.AbstractListModel.fireIntervalRemoved(AbstractListModel.java:179)
    at javax.swing.DefaultComboBoxModel.removeAllElements(DefaultComboBoxModel.java:174)
    at javax.swing.JComboBox.removeAllItems(JComboBox.java:771)
    at mods.giantnuker.random_trivia.Gui.ref(Gui.java:264)
    at mods.giantnuker.random_trivia.Gui.itemStateChanged(Gui.java:258)
    at javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1223)
    at javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1280)
    at javax.swing.JComboBox.contentsChanged(JComboBox.java:1329)
    at javax.swing.AbstractListModel.fireContentsChanged(AbstractListModel.java:118)
    at javax.swing.DefaultComboBoxModel.setSelectedItem(DefaultComboBoxModel.java:93)
    at javax.swing.DefaultComboBoxModel.addElement(DefaultComboBoxModel.java:131)
    at javax.swing.JComboBox.addItem(JComboBox.java:716)
    at mods.giantnuker.random_trivia.Gui.ref(Gui.java:267)
    at mods.giantnuker.random_trivia.Gui.itemStateChanged(Gui.java:258)
    at javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1223)
    at javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1271)
    at javax.swing.JComboBox.contentsChanged(JComboBox.java:1329)
    at javax.swing.JComboBox.intervalRemoved(JComboBox.java:1351)
    at javax.swing.AbstractListModel.fireIntervalRemoved(AbstractListModel.java:179)
    at javax.swing.DefaultComboBoxModel.removeAllElements(DefaultComboBoxModel.java:174)
    at javax.swing.JComboBox.removeAllItems(JComboBox.java:771)
    at mods.giantnuker.random_trivia.Gui.ref(Gui.java:264)
    at mods.giantnuker.random_trivia.Gui.itemStateChanged(Gui.java:258)
    at javax.swing.JComboBox.fireItemStateChanged(JComboBox.java:1223)
    at javax.swing.JComboBox.selectedItemChanged(JComboBox.java:1280)
    at javax.swing.JComboBox.contentsChanged(JComboBox.java:1329)
    at javax.swing.AbstractListModel.fireContentsChanged(AbstractListModel.java:118)
    at javax.swing.DefaultComboBoxModel.setSelectedItem(DefaultComboBoxModel.java:93)
    at javax.swing.DefaultComboBoxModel.addElement(DefaultComboBoxModel.java:131)
    at javax.swing.JComboBox.addItem(JComboBox.java:716)
    at mods.giantnuker.random_trivia.Gui.ref(Gui.java:267)

...继续

2 个答案:

答案 0 :(得分:1)

boolean err = true;
while(err) {  
    try {
        points = Integer.valueOf(txt2);
        err = false;
    } catch (NumberFormatException e) {
        txt2 = JOptionPane.showInputDialog(this, "Enter the amount of points for the Answer:", "Points...");
        if (txt2.equals("Points...")) 
            return;
    }
}

我正在研究这个问题。如果text2不是数字,它将抛出异常,并且不会将err设置为false。假设text2不等于&#34;点......&#34;

这可能会导致循环无限循环

答案 1 :(得分:1)

查看堆栈跟踪,我们发现了一个以ref()方法为中心的问题,并从JComboBox中删除了组件。

这里似乎有一个问题:

@Override
public void itemStateChanged(ItemEvent arg0) {
    Object src = arg0.getSource();
    if (src == questions) {
        ref();
    }
}

@SuppressWarnings("unchecked")
public void ref() {
    questions.removeAllItems();
    answers.removeAllItems();

    ...

您的ItemListener,(this - 已添加到JComboBoxes的问题和答案中)调用ref()方法,该方法更改两个JComboBox的状态,触发ItemListener,后者调用{ {1}}方法.....无限广告。

不要从其中一个侦听器中更改对象的状态,或者如果您绝对需要这样做,请先取消激活或删除侦听器,然后重新添加它们。例如,

ref()