【问题标题】:How can I implement loops and if-else logic for ActionListener?如何为 ActionListener 实现循环和 if-else 逻辑?
【发布时间】:2013-12-02 03:30:39
【问题描述】:

我正在尝试使用 Swing 构建一个简单的问答游戏。用户应该能够从组合框中挑选水果或蔬菜,并猜测它是水果还是蔬菜。如果他们猜对了,GUI 应该输出“yes”。如果他们猜错了,它应该输出“no”。代码似乎编译正确,但运行不正确。

我在“水果”和“蔬菜”按钮的 ActionListener 中使用了 if-else 循环,以确定用户是否猜对了。

public class GUI {

    public static String input;

    public static void main(String[] args) {

        new GUI();
    }

    public GUI()
    {


        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Simple GUI");
        frame.setSize(400,300);
        frame.setLocationRelativeTo(null);

        final String[] fruitOptions = {"Apple", "Apricot", "Banana"
                ,"Cherry", "Date", "Kiwi", "Orange", "Pear", "Strawberry"};



        final String[] vegOptions = {"Asparagus", "Beans", "Broccoli", "Cabbage"
                , "Carrot", "Celery", "Cucumber", "Leek", "Mushroom"
                , "Pepper", "Radish", "Shallot", "Spinach", "Swede"
                , "Turnip"};

        String[] combined = {"Apple", "Apricot", "Banana"
                ,"Cherry", "Date","Cucumber", "Leek", "Mushroom"
                , "Pepper", "Radish","Kiwi", "Orange", "Pear", "Strawberry", "Asparagus", "Beans", "Broccoli", "Cabbage"
                , "Carrot", "Celery","Shallot", "Spinach", "Swede"
                , "Turnip"};




        JPanel comboPanel = new JPanel();
        JLabel comboLabel = new JLabel("Is it a Fruit or Vegetable?:");
        final JComboBox fruitsVeggies = new JComboBox(combined);

        ActionListener actionListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                input = (String) fruitsVeggies.getSelectedItem();

            }
        };



        fruitsVeggies.addActionListener(actionListener);
        comboPanel.add(comboLabel);
        comboPanel.add(fruitsVeggies);


        final JButton fruitButton = new JButton( "Fruit");
        JButton vegButton = new JButton("Vegetable");



        final JLabel yes = new JLabel("YES");
        final JLabel no = new JLabel("NO");


        ActionListener listener = new ActionListener() 
        {



            public void actionPerformed (ActionEvent d)
            {
                int i;

                for(i=0; i<vegOptions.length-1; i++) 
                {
                    if (input.equals(fruitOptions[i])) 
                    {
                         yes.setVisible(true);
                    }
                    else
                        no.setVisible(true);
                }   




            }
        };


        ActionListener vegListener = new ActionListener() 
        { 


            public void actionPerformed(ActionEvent f)
            {
                int i;

                for(i=0; i<vegOptions.length-1; i++) 
                {
                    if (input.equals(fruitOptions[i])) 
                    {

                         no.setVisible(true);
                    }
                    else

                        yes.setVisible(true);
                }
            }
        };

        no.setVisible(false);
        yes.setVisible(false);
        fruitButton.addActionListener(listener);
        vegButton.addActionListener(vegListener);

        frame.add(comboPanel, BorderLayout.NORTH);

        frame.add(vegButton,BorderLayout.WEST);
        frame.add(fruitButton, BorderLayout.EAST);
        frame.add(yes, BorderLayout.CENTER);
        frame.add(no, BorderLayout.CENTER);


        frame.setVisible(true);
    }

}

【问题讨论】:

  • 那么具体是什么问题?您所说的只是“它没有正确运行”。输出是否与您的预期不同?哪些输入是这种情况?
  • 请对代码、输入/输出和结构化文档(如 HTML 或 XML)使用代码格式。为此,请选择示例并单击消息发布/编辑表单上方的{} 按钮。
  • 只是一个建议:使用一个 JLabel 和 setText() 方法来更改输出。

标签: java swing actionlistener


【解决方案1】:

你的问题在于下面的代码

public void actionPerformed (ActionEvent d)
{
    int i;
    for(i=0; i<vegOptions.length-1; i++) 
    {
        if (input.equals(fruitOptions[i])) 
        {
            yes.setVisible(true);
        }
        else
        {
            no.setVisible(true);
        }
    }
}

在循环的每次迭代中,您都在设置其中一个标签的可见性。相反,您应该检查循环中的结果,然后设置可见性。此外,您似乎只检查输入是否是水果,如果是,则将 yes 设置为可见。这不是一个正确的比较。您应该检查选择的类型是否与用户的猜测相符。

【讨论】:

    【解决方案2】:
    1. 将组件变量声明为方法的局部变量并不可取,尤其是当您需要使用匿名类的方法时,需要将组件变量声明为final。在类上下文中声明组件变量。

    2. 无需使用两个单独的JLabel 来显示YESNO 即可正确输入。使用一个JLabel 并利用JLabelsetText(string) 方法。当尚未做出决定时,请使用 resultNo answer is chosen 或对您有意义的类似名称。例如:

      answerLabel = new JLabel("No answer is chosen"); 
                  // answerLabel is a JLabel declared in class context
      
    3. 您的actionPerformed 函数存在错误,如下所示:

          public void actionPerformed (ActionEvent d)
         {
            int i;
      
          for(i=0; i<vegOptions.length-1; i++) 
          {
              if (input.equals(fruitOptions[i]))  //<---i  is bounded to vegOptions length
                           //but iterating over fruitOptions !!
                   answerLabel.setText("YES! Correct Answer");
      
              else
                  answerLabel.setText("NO! Wrong Answer");
          }   
      
      }
      

    和其他动作组件类似的变化,即两个JButton

    【讨论】:

      【解决方案3】:
      for(i=0; i<vegOptions.length-1; i++) 
      {
          if (input.equals(fruitOptions[i]))
              yes.setVisible(true);
          else
              no.setVisible(true);
      }
      

      这段代码是错误的。

      Sage 提到的第一个问题是 vegOptions.length-1 应该是 fruitOptions.length - 你检查的是水果,而不是蔬菜。

      另一个问题一开始可能并不明显。假设用户输入“apple”。代码检查“apple”(他们的输入)和“apple”(来自fruitOptions),并显示“yes”标签。然后代码检查“apple”(他们的输入)和“apricot”(来自fruitOptions)并显示“no”标签。循环结束后,“是”和“否”标签都将可见。

      这段代码应该可以工作。确保您了解它的工作原理:

      boolean isInArray = false;
      for(i=0; i<fruitOptions.length; i++) 
      {
          if (input.equals(fruitOptions[i]))
          {
              isInArray = true;
          }
      }
      
      if(isInArray)
      {
          yes.setVisible(true);
          no.setVisible(false);
      }
      else
      {
          no.setVisible(true);
          yes.setVisible(false);
      }
      

      请注意,这两个问题都与 ActionListener 无关。

      同样正如 Sage 所指出的,当您可以拥有一个并更改其上的文本时,没有必要拥有两个 JLabel。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-08
        • 1970-01-01
        相关资源
        最近更新 更多