如何为ActionListener实现循环和if-else逻辑?

时间:2013-12-02 03:30:40

标签: java swing actionlistener

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

我在“fruit”和“vegetable”按钮的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);
    }

}

3 个答案:

答案 0 :(得分:0)

您遇到的问题是以下代码

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设置为可见。这不是一个正确的比较。您应该检查选择的类型是否与用户猜测匹配。

答案 1 :(得分:0)

  1. 声明方法的组件变量是不可取的,尤其是当您需要使用匿名类的方法时,需要声明的组件变量为final。在类上下文中声明组件变量。

  2. 无需使用两个单独的JLabel来显示YESNO以获得正确的输入。使用一个JLabel并使用setText(string) JLabel方法。如果尚未做出决定,请使用对您有意义的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");
        }   
    
    }
    
  4. 对其他动作组件的类似更改,即两个JButton

答案 2 :(得分:0)

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),并显示“是”标签。然后代码检查“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并且更改它上面的文本时,不需要有两个JLabel。