在 actionPerformed 完成之前禁用单击按钮 java

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17807846/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-01 15:04:02  来源:igfitidea点击:

Disable button on click before actionPerformed is completed java

javaswingjbuttonactionlistenerevent-dispatch-thread

提问by Steve

I have a button doing a long function, I want to disable this button after the user once click on it to in order to prevent him from clicking it again many times

我有一个功能很长的按钮,我想在用户点击它后禁用这个按钮,以防止他再次点击它多次

The button gets disabled but the problem is after the function finished the button gets enabled again
i tried to put button.setEnabled(false);in a new thread but it didn't work either

按钮被禁用但问题是在功能完成后按钮再次启用
我试图放入button.setEnabled(false);一个新线程但它也不起作用

for testing this sample of code

用于测试此代码示例

button.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent ae) {
        button.setEnabled(false);
        for (int i = 0; i < Integer.MAX_VALUE; i++) {
            for (int j = 0; j < Integer.MAX_VALUE; j++) {
                for (int ii = 0; ii < Integer.MAX_VALUE; ii++) {
                }
            }
        }
    }
});

回答by trashgod

Use SwingWorkerfor long running background tasks. In this example, the startButtonaction does setEnabled(false), and the worker's done()implementation does setEnabled(true).

使用SwingWorker长期运行的后台任务。在这个例子中startButton动作是setEnabled(false),而工作器的done()实现是setEnabled(true)

回答by mKorbel

  • everything wrapped in public void actionPerformed(ActionEvent ae) {is done at one moment, (on the screen) when all code lines are executed, this is basic rule for AWT/Swing Listeners and EventDispatchThread

  • you need to delay event in EDT by using

    1. short delay with Swing Timer,
    2. redirect rest of code (after button.setEnabled(false);) to SwingWorker, easiest to Runnable#Thread, note all output from Runnable#Threadto the already visible Swing GUI must be wrapped into invokeLater
  • proper of ways will be only using Swing Actionand instead of locking the JButtonto set Action.setEnabled(false)only

  • public void actionPerformed(ActionEvent ae) {当所有代码行被执行时,所有包装在某一时刻(在屏幕上)完成,这是 AWT/Swing 侦听器和 EventDispatchThread 的基本规则

  • 您需要通过使用延迟 EDT 中的事件

    1. 摆动定时器的短延迟,
    2. 将其余代码(之后button.setEnabled(false);)重定向到SwingWorker,最容易Runnable#Thread,注意所有输出Runnable#Thread到已经可见的 Swing GUI 必须包装到invokeLater
  • 正确的方法将只使用Swing Action而不是锁定只JButton设置Action.setEnabled(false)

回答by Nirav Kamani

Edit: It's tempting to think you could use a mouse listener to implement this. For example, to prevent you could use mouse released event or mouse clicked event of mouse listener. Inside that you could write button.setEnable(false). Unfortunately, this also blocks the event dispatch thread.

编辑:很容易认为您可以使用鼠标侦听器来实现这一点。例如,为了防止您可以使用鼠标侦听器的鼠标释放事件或鼠标单击事件。在里面你可以写button.setEnable(false). 不幸的是,这也阻塞了事件调度线程