java - ActionListener 和 for 循环

标签 java swing loops for-loop actionlistener

亲爱的 Stackoverflow friend 们,

这是我正在尝试做的事情: - 我想要一个带有一些按钮和 JTextArea 的简单框架 - 我想要一个循环,在每次迭代时,期望我单击一个按钮:当我单击此按钮时,会发生一堆事情,但我无法正确执行: - 在一次尝试中,我让 for 循环工作,但它不会停止,每次,它只接受第一个命令并执行所有 20 个回合而不停止 - 在当前版本中,我单击按钮但没有任何反应 - 我已经研究过 SOF 和一系列其他网站,包括 Oracle 文档,但是(可能也是由于我的经验水平),我找不到足够清晰的解释让我理解

这是我的代码

package game4_prova_forloop;

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class GAME4_prova_forloop {

    public static void main(String[] args) {

        //create frame
        JFrame frame = new JFrame("Action Listener");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        frame.setLayout(new FlowLayout());
        frame.setVisible(true);   

        //crete text area panel, 
        JPanel pannelloTextArea = new JPanel(); 
        pannelloTextArea.setBackground(new Color(255, 204, 204));
        pannelloTextArea.setSize(400, 400);
        frame.add(pannelloTextArea); 
        GroupLayout pannelloTextAreaLayout = new GroupLayout(pannelloTextArea); 

        //create scrollPane
        JScrollPane scrollTextArea = new JScrollPane(); 

        //1) create JTextArea
        JTextArea mostraTesto = new JTextArea(20, 20); 
        mostraTesto.setLineWrap(true);  //make it wrap text 
            pannelloTextArea.add(scrollTextArea); //add it to scroll pane
            pannelloTextArea.revalidate();
                scrollTextArea.add(mostraTesto); //add the scroll pane to text area 
                scrollTextArea.setViewportView(mostraTesto); 

        //2) create buttons 
        JButton action1 = new JButton("1");
        frame.add(action1);
        JButton action2 = new JButton("2");
        frame.add(action2);
        JButton action3 = new JButton("3");
        frame.add(action3);

        //3) pass textArea in the RoundLevelAction class
        RoundLevelAction roundLevelActionObj = new RoundLevelAction(mostraTesto); //first issue: I get an error
        //4) add listener to JButtons
        action1.addActionListener(roundLevelActionObj);
        action2.addActionListener(roundLevelActionObj);
        action3.addActionListener(roundLevelActionObj);          
    }

//THIS IS WHERE I START TO HAVE PROBLEMS: WHEN I CLICK NOTHING HAPPENS, WHEN 
//I WOULD EXPECT THE FOR LOOP TO GO THROUGH ITERATIONS
    public class RoundLevelAction implements ActionListener {

        //add inside the listener the pieces of GUI that you'll use
        private JTextArea mostraTesto;
        private Object action1;
        private Object action2;
        private Object action3;
        private Object action4;
        private Object action5;
        private Object action6;

        //create class for JTextArea
        public RoundLevelAction(JTextArea mostraTesto){
            this.mostraTesto = mostraTesto; 
        }    

        //and, finally, what I really want to do: a loop that, at each turn, expects me to click on 
        //a button and does an action in response
        public void actionPerformed(ActionEvent e) {
            //now create the loop
            for (int round_counter=1; round_counter<21; round_counter++) {                                       
                if (e.getSource()==action1){                             
                    mostraTesto.append("\n description action 1 and a bunch of other stuff");
                }
                else if (e.getSource()== action2){ 
                    mostraTesto.append("\n description action 2 and a bunch of other stuff");
                } 
                else if (e.getSource()== action3){
                    mostraTesto.append("\n description action 3 and a bunch of other stuff");
                } 
            }
        }
    }

}

重要提示:我很清楚上面的代码不符合 Java 最佳实践:它只是一个示例代码来说明我想要做什么(原始代码是多个类中的很多行)

我希望你能帮助我了解我做错的地方

提前非常感谢

最佳答案

为什么您的代码当前无法工作,以及您之前的尝试可能出了什么问题。

action1.addActionListener(roundLevelActionObj);
action2.addActionListener(roundLevelActionObj);
action3.addActionListener(roundLevelActionObj);  

这将为每个按钮添加相同的监听器。当您单击这两个按钮中的任何一个时,都会生成一个 ActionEvent 并将其发送到 ActionListener

当您的 ActionListener 中有一个 for 循环时,每次您单击这些按钮中的任何一个时都会执行整个循环。执行的是 actionPerformed 方法中的整个代码块。这可能是您在第一次尝试时发现的。

您当前的尝试在 for 循环中进行了 if (e.getSource()==action1) 检查。但是,该语句中的 action1 与您单击的按钮不同。这里的action1指的是字段

private Object action1;

在您的RoundLevelAction 类中。如果您使用调试器,您将看到这些 if 语句的计算结果都不为 true,这就是为什么您会觉得什么也没有发生。 事实上,for 循环被触发,但没有输出任何内容,因为没有一个 if 语句被评估为 true。

如果您使用调试器并放置一些断点,以上所有内容都可以轻松发现。

现在来解决您的问题。我不清楚。

I would like to have a loop that, at every iteration, expects for me to click on a button

此要求的问题在于 Swing 是单线程的。这意味着所有与 Swing 相关的操作都应该发生在单个线程(E(vent)D(ispatch(T(hread)))上,并且同一线程用于处理用户输入(例如鼠标单击)并绘制 UI .这也意味着,如果您以某种方式阻止该单个线程,您的 UI 就会变得不负责任。

因此,如果您有循环,则不能简单地阻止 EDT 并等待按钮单击。由于 EDT 被屏蔽,因此无法点击 EDT。

  • 要么在一个单独的线程上循环,然后在该线程中等待,直到用户单击按钮。然后,与该按钮关联的 ActionListener 可以重新激活线程
  • 您可以显示一个对话框,询问用户下一步要做什么,并将这些按钮放入该对话框中。查看 JOptionPane#show... 方法。

关于java - ActionListener 和 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28416272/

相关文章:

java - 如何从 Resultset 构造数组数组

java - 编译器看不到main方法

c - 从另一个 c 文件迭代 c 数组,隐藏结构变量

c++ - 循环菜单重复自己

java - 使用java运行python

java - 无法使用 riak 进行映射缩减

java - 如何用特殊字符替换字符串的一部分

Java Swing : How to invoke stopCellEditing() before TreeListeners:valueChanged?

java - 通过 VisualVM 发现文件 I/O 瓶颈

javascript - Kendo Grid.dataItem 循环不工作