Java:当JMenuItem多次调用方法时,JTextField会创建无限循环

时间:2012-11-01 16:21:41

标签: java swing jtextfield

我正在为大学写一篇文本分析程序,要求你在字典中添加一个单词以及其他动作。我对代码的这一部分有问题,因为如果用户在JTextField为空时点击确定,我需要出现一条错误消息。我可以得到它,但以某种方式创建了一个无限循环与错误消息。请帮助,我看了整个互联网,但找不到这样一个简单的bug的答案。这是我的代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import java.lang.Character;

public class TAPtest implements ActionListener
{
 private JFrame tap = new JFrame("Text Analysis"); 
 private JMenuBar tapMenu = new JMenuBar();
 private JMenu dictionary = new JMenu("Dictionary");
 private JMenuItem addWord = new JMenuItem("Add Word");
 private JFrame frameAdd = new JFrame("Add Word");
 private JLabel add = new JLabel("Enter word to add:");
 private JButton okNewWord = new JButton("Ok");
 private JButton cancelNewWord = new JButton("Cancel");
 private JTextField inputNewWord = new JTextField(28);
 private JPanel westAdd = new JPanel();
 private JPanel eastAdd = new JPanel();
 private JPanel southAdd = new JPanel();
 private Vector <String> dictionaryVector = new Vector<String>();

 public TAPtest() //Constructor. Contains TAP GUI.
 {  
   tap.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   tap.setSize(350, 100);
   tap.setLocation(700, 500);
   tap.setResizable(false); 
   tap.setJMenuBar(tapMenu);
   tapMenu.add(dictionary);
   dictionary.add(addWord);

   addWord.addActionListener(this);

   tap.setVisible(true);
 }

 public void actionPerformed(ActionEvent event) //All actions performed.
 {
   if (event.getActionCommand() == "Add Word") addNewDicWordGUI();

   if (event.getSource() == okNewWord) addNewDicWord();
   if (event.getSource() == cancelNewWord) frameAdd.dispose();
 }

 public void addNewDicWordGUI()
 {
   frameAdd.setSize(350, 150);
   frameAdd.setLocation(700, 500);
   frameAdd.setResizable(false); 

   okNewWord.setSize(5,20);
   cancelNewWord.setSize(5,20);

   westAdd.add(add);
   eastAdd.setLayout(new GridLayout(2,1));
   eastAdd.add(okNewWord);
   eastAdd.add(cancelNewWord);
   southAdd.add(inputNewWord);

   frameAdd.add(westAdd, BorderLayout.WEST);
   frameAdd.add(eastAdd, BorderLayout.EAST);
   frameAdd.add(southAdd, BorderLayout.SOUTH);

   okNewWord.addActionListener(this);
   cancelNewWord.addActionListener(this);
   inputNewWord.addActionListener(this);

   frameAdd.setVisible(true);
 }

 public void addNewDicWord() 
 {
   String inputNew = inputNewWord.getText(); //Get JTextField value.
   inputNew = inputNew.toLowerCase();
   frameAdd.dispose();
   if (inputNew.equals("")) 
    JOptionPane.showMessageDialog(null, "You must enter a word", "Notice", 1);
   else {
    boolean addItemFound = dictionaryVector.contains(inputNew); //True if contains.
   if(addItemFound) //If true.
JOptionPane.showMessageDialog(null, inputNew + " already exists in the dictionary.", "Word Already Exists", 1);
   else { //If not true.
    dictionaryVector.addElement(inputNew); //Add the word to the dictionary Vector.
Collections.sort(dictionaryVector); //Sort the vector in ascending order.
JOptionPane.showMessageDialog(null, inputNew + " was added to the dictionary.", "Word Added", 1);
   }
   inputNewWord.setText(null);
 }
}

public static void main(String [] args)
{
  TAPtest program = new TAPtest();
}
}

2 个答案:

答案 0 :(得分:1)

private Vector <String> dictionaryVector = new Vector<String>();
inputNewWord.setText(null);
JOptionPane.showMessageDialog(null, "You must enter a word", "Notice", 1);
public void actionPerformed(ActionEvent event) //All actions performed.
{
    ...
}

最好是

private SortedSet<String> dictionaryVector = new TreeSet<String>();
inputNewWord.setText("");
JOptionPane.showMessageDialog(null, "You must enter a word", "Notice",
         JOptionPane.ERROR_MESSAGE);
public void actionPerformed(ActionEvent event) //All actions performed.
{
    SwingUtilities.invokeLater(new Runnable() {
        @Override public void run() {
            ...
        }
    }
}

最后invokeLater可能导致了麻烦。事件处理actionPerformed是在事件线程上完成的,显示消息应该在之后 完成 处理事件(作为GUI保持响应的任何更长的任务)。

答案 1 :(得分:0)

像这样声明frameAdd -

private JFrame frameAdd = null;

addNewDicWordGUI()方法应该是这样的 -

public void addNewDicWordGUI()
{

           if(frameAdd==null)
               {

//Initialized only for the first time

            frameAdd = new JFrame("Add Word");


       frameAdd.setSize(350, 150);
       frameAdd.setLocation(100, 200);
       frameAdd.setResizable(false); 

       okNewWord.setSize(5,20);
       cancelNewWord.setSize(5,20);

       westAdd.add(add);
       eastAdd.setLayout(new GridLayout(2,1));
       eastAdd.add(okNewWord);
       eastAdd.add(cancelNewWord);
       southAdd.add(inputNewWord);

       frameAdd.add(westAdd, BorderLayout.WEST);
       frameAdd.add(eastAdd, BorderLayout.EAST);
       frameAdd.add(southAdd, BorderLayout.SOUTH);

       okNewWord.addActionListener(this);
       cancelNewWord.addActionListener(this);
       inputNewWord.addActionListener(this);
     }
      frameAdd.setVisible(true);
 }

进行上述更改,它将正常工作。