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 スタックが処理できるよりも長い文字列になります。

必要なリスナーは 1 つだけです。それらを追加し続けないでください。問題がなくなると思います。

于 2014-05-14T01:19:33.113 に答える
0

の無限再帰はAWTEventMulticaster、通常、それ自体の内部にコンポーネントを追加することによって発生します。貼り付けたコードからはどのように発生するかわかりませんが、バグはコードの他の部分にある可能性があります。

AWTEventMulticaster.mouseEntered() で無限再帰が発生する原因を参照してください。.

于 2012-11-17T22:56:23.087 に答える
-1

次回質問を投稿するときのアドバイス: SSCCEを提供してください。コードを実行したい場合は、欠落しているクラスによる一連のコンパイル エラーを修正し、main メソッドを自分で提供する必要がありました。WriterPanelクラスはエラーとはまったく無関係のようです。

さらに、コードを削除します。fixAnswersエラーがメソッドにあるという結論に達しました。topそうすれば、パネルと のコードを提供する必要はありませんquestion。問題を再現できる簡易バージョンについては、以下を参照してください。エラーを修正するには、その 1 行のコメントを外します。

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 に答える