2

我正在编写一个程序,该程序可以将一组问题写入​​文件以供另一个程序读取。可能的答案输入到底部的 JTextFields 中。它有代码确保最后不会有超过一个空白 JTextField。当我输入答案时,它会在不同的点抛出 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);
}

}

4

3 回答 3

1

每次键入一个键时,都会调用初始侦听器的 (this') keyTyped 方法,该方法调用 fixAnswers,最后一步,它会向您的 JTextField 添加另一个侦听器。您永远不会删除任何侦听器,因此最终您将拥有比 Java 堆栈可以处理的更长的字符串。

你只需要一个听众。不要继续添加它们,我怀疑你的问题会消失。

于 2014-05-14T01:19:33.113 回答
0

无限递归AWTEventMulticaster通常是由您在自身内部添加组件引起的。我无法从您粘贴的代码中看到这是如何发生的,但该错误可能在您代码的其他部分。

请参阅是什么导致 AWTEventMulticaster.mouseEntered() 中的无限递归?.

于 2012-11-17T22:56:23.087 回答
-1

A piece of advice the next time you post a question: provide an SSCCE. If we now wanted to run your code, we had to fix a bunch of compile errors due to missing classes and provide a main method ourself. The WriterPanel class seems to be completely unrelated to the error.

Further, strip down your code. You already came to the conclusion that the error was in the fixAnswers method. Then there is no need to provide us with code for the top panel and for the question. See below for a stripped down version which can reproduce the problem. Uncomment that one line to fix the error.

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 );
      }
    });
  }
}
于 2012-11-18T09:23:55.083 回答