Search code examples
javaswingjtextfield

Java: JTextField creates infinite loop when method called more than once from JMenuItem


I'm writing a Text Analysis Program for college that requires you to add a word to a dictionary as well as other actions. I'm having a problem with this section of the code as I need an error message to come up if the user hits ok while the JTextField is empty. I can get it going but have created an infinite loop somehow with the error message. Please help, I've looked all over the internet but can't find an answer for such a simple bug. Here is my code:

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();
}
}

Solution

  • Declare frameAdd like this -

    private JFrame frameAdd = null;
    

    The addNewDicWordGUI() method should be like this -

    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);
     }
    

    Make the above changes and it will work fine.