【问题标题】:Java: JTextField creates infinite loop when method called more than once from JMenuItemJava:当从 JMenuItem 多次调用方法时,JTextField 创建无限循环
【发布时间】:2012-11-01 16:21:41
【问题描述】:

我正在为大学编写一个文本分析程序,该程序要求您将一个单词添加到字典中以及其他操作。我的这部分代码有问题,因为如果用户在 JTextField 为空时点击 ok,我需要出现错误消息。我可以让它继续运行,但以某种方式创建了一个无限循环,并带有错误消息。请帮忙,我在网上找遍了,但找不到这么简单的错误的答案。这是我的代码:

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

【问题讨论】:

    标签: java swing jtextfield


    【解决方案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 保持响应的任何更长的任务)。

    【讨论】:

    • 您好,Joop,感谢您的帮助...我对 SwingUtilities.invoke 不了解,现在正在研究中,如果我可以让它工作,我会告诉您..
    【解决方案2】:

    像这样声明 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);
     }
    

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

    【讨论】:

    • 道歉 Mohsin,这非常有效......一个简单的解决方案,谢谢!
    猜你喜欢
    • 1970-01-01
    • 2016-04-09
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 2020-05-03
    • 2017-04-21
    • 1970-01-01
    • 2021-02-20
    相关资源
    最近更新 更多