我正在使用Java swing为我的java游戏制作关卡编辑器。
其中一个功能是有一个可切换的按钮可以打开和关闭游戏以测试关卡。游戏在一个jpanel内运行,然后你再次单击该按钮以解开它,然后关闭游戏。
我只希望用户在游戏未运行时能够在swing应用程序中更改内容或按钮,当它正在运行时我将焦点设置为游戏组件。他们应该能够推动的挥杆应用程序中唯一的按钮是切换按钮以关闭游戏。
问题是,我想不出一个好办法。使用递归函数我可以轻松地遍历并查找所有组件并执行setEnabled(false),但是当游戏关闭时,它无法知道先前启用的状态是什么(沿着其他问题,就像其他组件响应在其他组件上调用setEnabled)
我认为我真正需要的只是在游戏运行时直接“杀死”用户输入到swing应用程序中的某种方式..但最好还是再次单击切换按钮以返回应用程序的状态,在Jpanel内部运行的游戏需要能够集中注意力......
如果没有大量的“组织”代码来管理swing应用程序中的组件,有没有办法做这种事情?
答案 0 :(得分:2)
您可以将所有内容都放在地图中,就像这样。
class ComponentState {
private JComponent component;
private bool on;
// Getters & Setters
}
private Map<String, ComponentState> components = new HashMap<>();
为了向游戏中添加新组件:
components.add("startbutton", new ComponentState(new JButton, true));
然后将所有组件添加到您的屏幕:
for(String key : components.KeySet()) {
ComponentState comp = components.get(key);
if(comp.isOn()) { this.add(comp.getComponent()) };
}
并禁用/激活组件:
components.get("myActivatedComponent").disable(); // disable is a self defined method
答案 1 :(得分:2)
您需要一个disableAll()
方法将每个组件设置为禁用状态,并使用resetAll()
方法将每个组件状态重置为其先前状态。您需要在禁用它时保存每个组件的状态,以便能够在之后恢复它。这需要O(n)
空间。
private final Map<JComponent, Boolean> components = new HashMap<JComponent, Boolean>();
public void disableAll(JComponent root) {
components.put(root, root.isEnabled());
root.setEnabled(false);
for (int i=0, n=root.getComponentCount(); i<n; i++) {
JComponent child = (JComponent) root.getComponentAt(i);
disableAll(child);
}
}
public void resetAll(JComponent root) {
boolean status = components.get(root);
root.setEnabled(status);
for (int i=0, n=root.getComponentCount(); i<n; i++) {
JComponent child = (JComponent) root.getComponentAt(i);
resetAll(child);
}
}
答案 2 :(得分:1)
另一个选择是使用GlassPane
和“灰色”组件区域。您还必须捕获并忽略窗格中针对您不希望用户单击的区域的点击次数。
请参阅Java教程中的示例:http://docs.oracle.com/javase/tutorial/uiswing/components/rootpane.html
这篇文章也可能有所帮助: https://weblogs.java.net/blog/alexfromsun/archive/2006/09/a_wellbehaved_g.html