亲爱的 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/