我正在编写一个程序,可以将一组问题写入审阅文件,供另一个程序阅读。可能的答案输入底部的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);
}
}
答案 0 :(得分:1)
每次键入一个键时,都会调用初始侦听器(此&#39;)keyTyped方法,调用fixAnswers,最后一步,它会向JTextField添加另一个侦听器。您永远不会删除任何侦听器,因此最终您拥有比Java堆栈可以处理的更长的字符串。
你只需要一个听众。不要继续添加它们,我怀疑你的问题会消失。
答案 1 :(得分:0)
AWTEventMulticaster
中的无限递归通常是由您自己添加组件引起的。我无法看到你粘贴的代码会发生什么情况,但错误可能出现在代码的其他部分。
请参阅What causes an endless recursion in AWTEventMulticaster.mouseEntered()?。
答案 2 :(得分:-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 );
}
});
}
}