For循环不等待JTextField中的用户响应

时间:2013-12-09 03:53:17

标签: java for-loop actionlistener

再次寻求帮助,为家庭作业找出一些东西。我已经完成了大部分工作,但是我很难理解为什么我不能让for-loop等待用户文本输入。基本上,我需要程序提示用户输入记忆中的颜色。颜色作为字符串包含在数组中。在for循环的每次迭代中,我都希望动作监听器检查并查看是否输入了正确的文本。如果是这样,该框应该将它的JLabel文本从“输入颜色编号x”更改为“输入颜色编号x + 1”

这是我注意到的: 我的for循环在整个迭代周期中运行,甚至考虑让用户在文本中键入文本。因此,不是提示用户输入颜色编号1,而是将颜色改为5号。

这是我得到的代码:

import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.awt.event.*;

public class ColorGame extends JFrame
{
  private static final int WIDTH = 300;
  private static final int HEIGHT = 200;
  //Text field that will confirm a user submission
  private JTextField colorEntry = new JTextField(10);  
  private int colorIndex = 0; //current index of colorSequence
  //String Array of colors to be searched for and validated in a text field
  private String[] colorSequence = {"red", "white", "yellow", "green", "blue"};

  public ColorGame()
  {
    setTitle("Memory Game");
    setSize(WIDTH, HEIGHT);
    setLayout(new FlowLayout());
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    createContents();
    setVisible(true);
  }

  public void createContents()
  {
    //dialog box to inform user of program's purpose
    JOptionPane.showMessageDialog(null, "How good is your memory?\nTry to memorize "
        + "this color sequence:\n\nred, white, yellow, green, blue"); 
    //JLabel to prompt user for color
    JLabel colorPrompt = new JLabel();

    add(colorPrompt);
    add(colorEntry);

    for(int i = 0; i < colorSequence.length; i++)
    {
      colorIndex = i + 1;
      colorPrompt.setText("Enter color number " + colorIndex + ":");
      colorEntry.addActionListener(new Listener());  
    }
  }

  private class Listener implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    {
      String colorText = "";

      colorText = colorEntry.getText();
      if(colorText.equals(colorSequence))
        System.out.println("Hello");
      else
        System.out.println("No");

    }
  }

  public static void main(String[] args)
  {
    new ColorGame();
  }
}

2 个答案:

答案 0 :(得分:2)

你的for循环是逐行运行命令行程序的代码,但这不是事件驱动的GUI的工作方式。

相反,您希望ActionListener中的代码推进计数器并根据该计数器更改行为。

private class Listener implements ActionListener
{

  int counter = 0;
  public void actionPerformed(ActionEvent e)
  {
    switch (count) {
      case 0:
        // do something for 0
        // including changing JLabel text if need be
        break;            
      case 1:
        // do something for 1
        break;
      case 2:
        // do something for 2
        break;
      default;
        // do something for default
    }
    count++;

  }
}

for循环将立即循环,无需关心用户输入或按下按钮。关键是你要改变程序的 状态 ,具体取决于按下JButton的次数。而且由于按下按钮会触发状态变化,因此无需担心某些循环循环过快。


这是一个相关的示例,不是一个确切的解决方案,但应该为您的解决方案提供一些想法:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;    
import javax.swing.*;

public class ChangeState {

   public static final String[] STRINGS = {
      "Enter the 1st String:",
      "Enter the 2nd String:",
      "Enter the 3rd String:"
   };

   private static void createAndShowGui() {
      final JTextField textField = new JTextField(10);
      final String[] replies = new String[STRINGS.length];
      final JLabel label = new JLabel(STRINGS[0]);
      JPanel mainPanel = new JPanel();
      mainPanel.add(label);
      mainPanel.add(textField);

      textField.addActionListener(new ActionListener() {
         int count = 0;
         @Override
         public void actionPerformed(ActionEvent arg0) {
            if (count < STRINGS.length) {
               replies[count] = textField.getText();
               count++;
               if (count < STRINGS.length) {
                  label.setText(STRINGS[count]);
               } else {
                  label.setText("Done!");
                  System.out.println("Replies:");
                  for (String reply : replies) {
                     System.out.println(reply);
                  }
               }
               textField.setText("");
            } 
         }
      });

      JFrame frame = new JFrame("ChangeState");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

答案 1 :(得分:0)

基本上,我最终弄清楚我不需要在createContents()中重复我的动作,并且我的动作会通过监听器重复。您对事件驱动编程的评论对我有所帮助。

private class Listener implements ActionListener   
{
  //counter to dynamically change numeric text values 
  //as well as to mark progress through colorSequence
  int count = 1; 
  public void actionPerformed(ActionEvent e)
  {
    if (count < colorSequence.length)
    {
      if (colorEntry.getText().equals(colorSequence[count - 1]))
      {
        count++;
        colorEntry.setText("");
        colorPrompt.setText("Enter color number: " + count);
      }
      else
      {
        colorEntry.setVisible(false);
        colorPrompt.setText("Sorry - wrong answer. Eat more antioxidants.");
      }
    } //end if (for while the program is still iterating through the array)
    else
    {
      colorPrompt.setText("Congratulations - your memory is perfect");
      colorEntry.setVisible(false);
    } //end else (the user has properly stepped through all the colors in the array)
  } //end actionPerformed   
} //end private class Listener