Java 如何防止通过控制台的输入优先于禁用按钮?
我有一些代码创建了一个窗口,其中包含一些按钮,当单击这些按钮时,会提示用户通过控制台进行输入(注意:我在NetBeans中运行这个程序)。现在我想继续使用控制台,所以我并不是在寻找一个解决方案,在这个解决方案中,我创建了一个新的框架,通过GUI请求输入 问题是,当console从用户那里获取输入时,所有按钮都仍然处于启用状态,因此,当用户完成向console输入内容时,所有按下的按钮都会排队等待,并且这些按钮会被执行。我想在控制台接收输入时禁用这些按钮。我认为按钮的.setEnabled(false)方法可以做到这一点,我认为通常情况下也可以。Java似乎优先考虑用户输入,因此在用户完成对控制台的输入之前,按钮不会被禁用。一旦用户完成输入,按钮应该被重新启用,因此它们实际上永远不会被禁用。有关守则如下:Java 如何防止通过控制台的输入优先于禁用按钮?,java,swing,Java,Swing,我有一些代码创建了一个窗口,其中包含一些按钮,当单击这些按钮时,会提示用户通过控制台进行输入(注意:我在NetBeans中运行这个程序)。现在我想继续使用控制台,所以我并不是在寻找一个解决方案,在这个解决方案中,我创建了一个新的框架,通过GUI请求输入 问题是,当console从用户那里获取输入时,所有按钮都仍然处于启用状态,因此,当用户完成向console输入内容时,所有按下的按钮都会排队等待,并且这些按钮会被执行。我想在控制台接收输入时禁用这些按钮。我认为按钮的.setEnabled(fal
for(int i = 0; i < LABELS.length; i++) {
menu_a.add(new JButton(LABELS[i]));
menu_a.get(i).addActionListener((ActionEvent e) -> {
menu_a.stream().forEach((b) -> {b.setEnabled(false);});
menu_b.stream().forEach((b) -> {b.setEnabled(false);});
menu_c.stream().forEach((b) -> {b.setEnabled(false);});
if(!menu_a.get(menu_a.indexOf(e.getSource())).isEnabled()) {
MenuActions.MenuActions(menu_a.indexOf(e.getSource()) + 1, data);
menu_a.stream().forEach((b) -> {b.setEnabled(true);});
menu_b.stream().forEach((b) -> {b.setEnabled(true);});
menu_c.stream().forEach((b) -> {b.setEnabled(true);});
}
});
itemPanel.add(menu_a.get(i));
}
for(int i=0;i{
菜单_a.stream().forEach((b)->{b.setEnabled(false);});
menu_b.stream().forEach((b)->{b.setEnabled(false);});
menu_c.stream().forEach((b)->{b.setEnabled(false);});
如果(!menu_a.get(menu_a.indexOf(e.getSource())).isEnabled()){
MenuActions.MenuActions(menua.indexOf(e.getSource())+1,数据);
菜单_a.stream().forEach((b)->{b.setEnabled(true);});
menu_b.stream().forEach((b)->{b.setEnabled(true);});
menu_c.stream().forEach((b)->{b.setEnabled(true);});
}
});
itemPanel.add(menu_a.get(i));
}
标签只是一个字符串数组,这些字符串是按钮的标签
MenuActions是一个基于按钮索引的类,它通过控制台提示用户输入不同类型的输入
数据是一个对象,它包含的数据是根据用户输入进行操作的,与我认为的问题无关。所以@MadProgrammer是对的。我必须查找并实现一个SwingWorker,以使代码按我所希望的方式执行。结果是这样的: 编辑:所以我不知道我在原始上下文之外修改GUI元素是在犯反人类罪。我更改了代码,现在看起来像这样
for(int i = 0; i < LABELS.length; i++) {
menu_a.add(new JButton(LABELS[i]));
menu_a.get(i).addActionListener((ActionEvent e) -> {
menu_a.stream().forEach((b) -> {b.setEnabled(false);});
menu_b.stream().forEach((b) -> {b.setEnabled(false);});
menu_c.stream().forEach((b) -> {b.setEnabled(false);});
new SwingWorker<Void, Void>() {
@Override
public Void doInBackground() {
menuActions(menu_a.indexOf(e.getSource()) + 1);
return null;
}
@Override
public void done() {
menu_a.stream().forEach((b) -> {b.setEnabled(true);});
menu_b.stream().forEach((b) -> {b.setEnabled(true);});
menu_c.stream().forEach((b) -> {b.setEnabled(true);});
}
}.execute();
});
panel_a.add(menu_a.get(i));
}
for(int i=0;i{
菜单_a.stream().forEach((b)->{b.setEnabled(false);});
menu_b.stream().forEach((b)->{b.setEnabled(false);});
menu_c.stream().forEach((b)->{b.setEnabled(false);});
新SwingWorker(){
@凌驾
公共无效doInBackground(){
菜单操作(菜单a.indexOf(e.getSource())+1);
返回null;
}
@凌驾
公众假期结束(){
菜单_a.stream().forEach((b)->{b.setEnabled(true);});
menu_b.stream().forEach((b)->{b.setEnabled(true);});
menu_c.stream().forEach((b)->{b.setEnabled(true);});
}
}.execute();
});
面板添加(菜单获取(i));
}
我创建了一个匿名的SwingWorker来满足我的需求。最后,我不得不禁用doInBackground()方法中的按钮,否则它将无法禁用它们,而我被原来的问题困住了。(请参见下面的编辑)此外,menuActions现在指的是类中的私有方法,我认为因为它实际上只从GUI调用,所以我最好将其移入
编辑:所以我将禁用更改为在SwingWorker之外进行,现在它工作正常。我会责怪我没有保存我的更改,也许我是在重新编译旧代码
我还发现了更多关于SwingWorker和EventDispatchThread业务的信息,我觉得这些信息是相关的,帮助我更好地理解事情
工作流程
SwingWorker的生命周期涉及三个线程:
当前线程:在此线程上调用execute()方法。信息技术
安排SwingWorker在工作线程上执行并返回
立即可以等待SwingWorker使用
获取方法
工作线程:在此线程上调用doInBackground()方法。
这是所有背景活动应该发生的地方。通知
PropertyChangeListeners关于绑定属性更改使用
firePropertyChange和getPropertyChangeSupport()方法。默认情况下
有两个绑定属性可用:状态和进度
事件分派线程:所有与Swing相关的活动都发生在此线程上
线SwingWorker调用process和done()方法和
通知此线程上的所有PropertyChangeListeners
再次感谢@MadProgrammer为我指明了正确的方向,并及时让我知道我的原始代码非常糟糕
另外,我从这个答案中导出了代码:听起来更像是在阻止事件调度线程,有关更多详细信息,请参阅。一个可能的解决方案可能是使用从用户处读取输入no,no,no,oh出于理智之爱no。不要,永远不要从事件调度线程的上下文之外创建或修改任何UI组件,您的代码违反了Swing的单线程规则,这可能会导致无法描述的问题和奇怪。禁用
ActionListener
中的按钮,创建一个SwingWorker
,并从doInBackground
中的用户处获取输入,这将防止UI被阻止并变得无响应。制造