java - ActionListener 和动态(?)GUI
问题描述
我在这里阅读了十几个与 actionlistener/loop 相关的问题,但我不确定我是否找到了答案。我开始了我的第一个大型 Java 项目,这是一个文本 RPG,它包含大约 5K 行逻辑和游戏功能,仅使用控制台就可以按预期运行 - 当我决定尝试为它构建一个 Java swing GUI 时。这是我的问题:
我使用 Room 对象来处理玩家所在位置的描述,并且还有一系列选项供玩家选择下一个选项,它根据房间的 id 在 csv 文件中的哪个单元格以及旁边的内容动态创建. 我停止将其输出到控制台,而是开始基于选项数组创建 JButton,如下所示:
public void showNarrate(){
add(dd,gridConstraints);
optionCopy.clear();
int i = 0;
for(JButton j : optionButtons){
//adding and formatting buttons to gridBagConstraint I also set actionCommand for each button to the triggerValue (ID of the next room which the button should take the player to)
}
//I tried using a copy of my JButton array here so I could have something to iterate over in actionListener after clearing out the original
//(Since it needs to be cleared so the next Room's buttons can be built after the player chooses an option)
for(JButton j : optionButtons){
optionCopy.add(j);
}
optionButtons.clear();
//dd is a seperate drawingComponent I used for outputting room descriptions which may be totally unnecessary at this point :/
dd.repaint();
setVisible(true);
}
在 actionlistener (Same class) 中,这就是我尝试摆动它的方式:
for(JButton j : optionCopy){
if(e.getActionCommand().equals(j.getActionCommand())){
Main.saveRoom = Main.currentRoom;
Main.currentRoom = j.getActionCommand();
System.out.println(Main.currentRoom);
}
}}
然后在我的主要课程中我调用: narrator.narrate(currentRoom, saveRoom); 它负责处理与锁门、遭遇等有关的其他逻辑。在主循环中还有一些与自动保存和跟踪玩家访问过的房间相关的其他方法。我从我在这里读到的其他 q/a 知道这都是非常糟糕的设计,我现在开始理解这一点,但我的问题是:
游戏的第一个房间加载正常,当我单击一个按钮时,它会输出到控制台(仅用于测试)按钮应该调用的房间的正确触发值,所以我已经走了那么远,但我怎么能打电话现在又用同样的方法了吗?
- 如果我从 actionListener 调用 narrate,它会再次调用自己并抱怨 ConcurrentModification。
- 如果我尝试在我的 Main 类中保持循环,它将继续循环并且不允许玩家实际选择按钮。
我以前从未使用过线程,我想知道这可能是答案,最接近我找到的相关答案的是: Java: Method wait for ActionListener in another class 但我不认为将 actionListener 移动到 Main类将解决我的问题,即 actionListener 以递归方式结束调用自身。至于观察者可观察的模式......我只是无法理解它:(
我感谢任何和所有的帮助,我学到了很多东西,试图在不寻求帮助的情况下让这件事发挥作用,但这让我很难过。
解决方案
您的循环仅使用给定的 actionCommandactionPerformed
检查您是否JButton
存在a。optionList
然而,这可以在实际做某事之前完成:
boolean contained = false;
for (JButton j : optionButtons)
if (j.getActionCommand().equals(e.getActionCommand()))
contained = true;
if (contained) {
// change room
}
现在您可以调用narrate
了,因为您事先已经完成了对集合的迭代并且不会得到ConcurrentModificationException
推荐阅读
- php - laravel 服务器上的 jpeg 格式图像出现 404 错误
- java - 使用查询检索数据后,如何将数据更新回数据库?
- nuget - 从输出目录中排除带有 x64 dll 的 nuget 包?
- php - 通过从每个字符串解析的数字对 PHP 中的字符串数组进行排序
- iphone - iphone(ios)pf过滤器绕过每个主机的vpn
- ios - iOS / Swift:当触摸事件在 UIButton 上启动时,如何向上或向下滚动视图?
- ruby-on-rails - 尽管预检 OPTIONS 请求和 POST 成功,但 CORS 错误和意外的 404 错误
- sql - PostgreSQL 并不始终使用部分索引
- r - 你如何传播R中数据框中两个变量的对应最大值的错误?
- macos - Gstreamer 进程在 OSX 上以 Hello World 示例完成退出代码 132