2012-11-17 22 views
2

我正在編寫一個程序,可以將需要審閱的問題集寫入另一個程序讀取的文件中。可能的答案被輸入到底部的JTextFields中。它有代碼確保最後不會出現多個空白的JTextField。當我輸入答案時,在不同的點上它會拋出一個StackOverflowError。KeyListener中意外的StackOverflowError

堆棧跟蹤:

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError 
    at java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:232) 
    at java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:232) 
    at java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:232) 
    at java.awt.AWTEventMulticaster.keyPressed(AWTEventMulticaster.java:232) 

,代碼:現在縮短!

package writer; 

import java.awt.BorderLayout; 
import java.awt.GridLayout; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.util.ArrayList; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JSplitPane; 
import javax.swing.JTextArea; 
import javax.swing.JTextField; 

public class MyPanel extends JPanel implements KeyListener 
{ 
    private MutableQuestion current; 
    private WriterPanel writer; 
    private JPanel top=new JPanel(new BorderLayout()),answerPanel=new JPanel(new GridLayout(0,1)); 
    private JSplitPane split; 
    private JTextField title=new JTextField(); 
    private JTextArea question=new JTextArea(); 
    private ArrayList<JTextField> answers=new ArrayList<JTextField>(); 
    public MyPanel() 
    { 
    super(new BorderLayout()); 
     this.add(title,BorderLayout.PAGE_START); 
     split=new JSplitPane(JSplitPane.VERTICAL_SPLIT,true,new JScrollPane(question),new JScrollPane(answerPanel)); 
    split.setDividerLocation(150); 
    this.add(split,BorderLayout.CENTER); 
    answers.add(new JTextField()); 
    answerPanel.add(answers.get(0)); 
    answers.get(0).addKeyListener(this); 
} 
private void back(){} 
private void fitTitle(){} 
private void fixAnswers() 
{ 
    //System.out.println(answers); 
    while(answers.get(answers.size()-1).getText().equals("")&&answers.size()>1&&answers.get(answers.size()-2).getText().equals("")) 
     removeAnswer(answers.size()-1); 
    if(!answers.get(answers.size()-1).getText().equals("")) 
    { 
     answers.add(new JTextField()); 
     answerPanel.add(answers.get(answers.size()-1)); 
     answers.get(answers.size()-2).removeKeyListener(this); 
     //answers.get(answers.size()-1); 
     answerPanel.revalidate(); 
    } 
    answers.get(answers.size()-1).addKeyListener(this); 
} 
private void removeAnswer(int i){} 
public void keyTyped(KeyEvent e) 
{ 
    fixAnswers(); 
} 
public void keyPressed(KeyEvent e) {} 
public void keyReleased(KeyEvent e) {} 
public void newQuestion(){} 
public void loadQuestion(int i){} 
public void saveQuestion(){} 
public void loadQuestion(MutableQuestion q){} 
public static void main(String[] args) 
{ 
    JFrame j=new JFrame(); 
    j.setSize(600,600); 
    j.add(new MyPanel()); 
    j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    j.setVisible(true); 
} 

}

+1

太多的代碼..(http://sscce.org/) – atamanroman

+0

我知道,你認爲最好的方法來縮短它的問題? – BillThePlatypus

+0

'而(answers.get(answers.size() - 1).getText()等於( 「」)&& answers.size()> 1個&& answers.get(answers.size() - 2).getText( ).equals(「」)){ removeAnswer(answers.size() - 1); 「我不知道那是幹什麼的,但它看起來根本有缺陷。無論那種邏輯是什麼,如果僅僅用新的眼光來看待,我會用它自己的方法來說明。 – Thufir

回答

-1

下次發佈問題時有一條建議:請提供SSCCE。如果我們現在想要運行你的代碼,我們必須修復一大堆由於缺少類而造成的編譯錯誤,並提供一個主要的方法。 WriterPanel類似乎與錯誤完全無關。

此外,剝離下來的代碼。您已經得出結論,該錯誤出現在fixAnswers方法中。那麼就不需要爲我們提供top面板和question的代碼。請參閱下面的可以重現問題的精簡版。取消註釋一行來解決錯誤。

package writer; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextField; 
import javax.swing.WindowConstants; 
import java.awt.BorderLayout; 
import java.awt.EventQueue; 
import java.awt.GridLayout; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.util.ArrayList; 

public class SetPanel extends JPanel implements KeyListener { 
    private JPanel answerPanel = new JPanel(new GridLayout(0, 1)); 
    private ArrayList<JTextField> answers = new ArrayList<JTextField>(); 

    public SetPanel() { 
    super(new BorderLayout()); 
    this.add(new JScrollPane(answerPanel), BorderLayout.CENTER); 
    answers.add(new JTextField()); 
    answerPanel.add(answers.get(0)); 
    answers.get(0).addKeyListener(this); 
    } 

    private void fixAnswers() { 
    while (answers.get(answers.size() - 1).getText().equals("") && answers.size() > 1 && answers.get(answers.size() - 2).getText().equals("")) 
     removeAnswer(answers.size() - 1); 
    if (!answers.get(answers.size() - 1).getText().equals("")) { 
     answers.add(new JTextField()); 
     answerPanel.add(answers.get(answers.size() - 1)); 
     answers.get(answers.size() - 2).removeKeyListener(this); 
     answerPanel.revalidate(); 
    } 
// answers.get(answers.size() - 1).removeKeyListener(this); 
    answers.get(answers.size() - 1).addKeyListener(this); 
    } 

    private void removeAnswer(int i) { 
    answers.remove(i); 
    answerPanel.remove(i); 
    answerPanel.revalidate(); 
    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
    } 

    @Override 
    public void keyPressed(KeyEvent e) { 
    fixAnswers(); 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 

    } 

    public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
     JFrame testFrame = new JFrame("TestFrame"); 
     testFrame.add(new SetPanel()); 
     testFrame.pack(); 
     testFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     testFrame.setVisible(true); 
     } 
    }); 
    } 
} 
+0

感謝您的想法,我就上手 – BillThePlatypus

1

每次你一鍵您最初的聽衆(這種)的keyTyped方法被調用,調用fixAnswers,並作爲最後一步,它增加了一個監聽到你的JTextField。你永遠不會刪除任何監聽器,所以最終你有一個比Java堆棧可以處理更長的字符串。

您只需要一個監聽器。不要一直添加它們,我懷疑你的問題會消失。