Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 单击后禁用JButton,单击后启用';他的工作_Java_Swing - Fatal编程技术网

Java 单击后禁用JButton,单击后启用';他的工作

Java 单击后禁用JButton,单击后启用';他的工作,java,swing,Java,Swing,我有一个JButton,它有一个actionListener,当我多次单击它时,它将完成与我单击次数相同的工作,下面是我的代码: mouseListener = new ActionListener() { public void actionPerformed(ActionEvent e) { JButton source = (JButton) e.getSource(); source.setEnable

我有一个JButton,它有一个actionListener,当我多次单击它时,它将完成与我单击次数相同的工作,下面是我的代码:

   mouseListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
                JButton source = (JButton) e.getSource();
                source.setEnabled(false);
                try {
                    RequestCommon.ctbCookie = jtf.getText();
                    System.out.println( RequestCommon.ctbCookie );
                    HttpURLConnection connection = HttpURLConnectionBuilder.getConnection(RequestCommon.login, RequestCommon.getCtb888Headers());
                    String connectionOuput = HttpURLConnectionBuilder.getConnectionOuput(connection);
                    System.out.println(connectionOuput);
                    new Player(new BufferedInputStream(new FileInputStream(new File("sounds/8.mp3")))).play();
                } catch (IOException e1) {
                    e1.printStackTrace();
                } catch (JavaLayerException e1) {
                    e1.printStackTrace();
                }
                source.setEnabled(true);
        }
    };
    jb1.addActionListener(mouseListener);

我希望无论在作业运行期间单击多少次,它都不会再次执行。作业完成后,如果我再次单击,作业将再次运行。我不知道如何操作,请告诉我是否知道,谢谢

I thing,您应该在执行代码之前使用
if
并检查按钮是否已启用

  JButton source = (JButton) e.getSource();
 if(source.isEnabled()) {
                 .
.
. 
execute your code

我希望我能帮助你。:)

长时间运行的代码不应在事件调度线程(EDT)上执行。您需要启动一个单独的线程来执行HTTP请求

最简单的方法是使用
SwingWorker
。您可以在启动工作程序之前禁用该按钮,然后该工作程序将调用一个
done()
方法,您可以启用该按钮

有关EDT和Swing worker工作示例的更多信息,请阅读上Swing教程的部分

编辑:

人们似乎对事件处理感到困惑。在处理下一个事件之前调用事件的侦听器。所以在“双击”按钮的情况下。该按钮在第一次单击时被禁用,长时间运行的任务将启动。然后在禁用按钮上接收第二次单击,因此不会调用ActionListener

这是我手头的一些旧代码,它是在SwingWorker出现之前编写的。“在新线程中启动”按钮的基本逻辑是:

  • 禁用该按钮,以便在处理过程中不能单击该按钮
  • 通过循环10次并休眠来模拟长时间运行的任务
  • 启用该按钮,以便可以再次执行任务
  • 代码如下:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    /*
    * A couple of notes about long running tasks and GUI updates:
    *
    * 1) all GUI painting should be done in the event thread
    * 2) GUI painting is not done until the event thread processing is done
    *
    * This means that long running code (database access, file processing ...)
    * should not be done in the event thread. A new thread can be created for
    * these tasks.
    *
    * Most Swing methods are not thread safe. If the long running task needs
    * to update the GUI for any reason then the SwingUtilities class
    * should be used to add code to the event thread.
    *
    * See the Swing tutorial on "Using Threads" for more information
    * http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
    */
    public class InvokeLaterTest extends JFrame
        implements ActionListener, Runnable
    {
        JLabel status;
        JButton eventThread;
        JButton newThread;
        JButton stop;
        Thread thread;
        int i;
        boolean stopProcessing;
    
        public InvokeLaterTest()
        {
            status = new JLabel( "Ready to Process:" );
            status.setHorizontalAlignment( JLabel.CENTER );
            getContentPane().add(status, BorderLayout.NORTH);
    
            eventThread = new JButton( "Start in Event Thread" );
            eventThread.addActionListener( this );
            getContentPane().add(eventThread, BorderLayout.WEST);
    
            newThread = new JButton( "Start in New Thread" );
            newThread.addActionListener( this );
            getContentPane().add(newThread, BorderLayout.EAST);
    
            stop = new JButton( "Stop Processing" );
            stop.addActionListener( this );
            getContentPane().add(stop, BorderLayout.SOUTH);
        }
    
        public void actionPerformed(ActionEvent e)
        {
            //  Code is executing in Event thread so label will not be updated
            //  and the Stop button will not be enabled.
    
            if (e.getSource() == eventThread)
            {
                stopProcessing = false;
                run();
            }
    
            //  Code is executing in a new thread so label will be updated
    
            else if (e.getSource() == newThread)
            {
                stopProcessing = false;
                thread = new Thread( this );
                thread.start();
            }
            else
            {
                stopProcessing = true;
                status.setText("Processing Stopped");
                setButtons( true );
            }
        }
    
        public void run()
        {
            setButtons( false );
    
            for (i = 1; i < 10; i++)
            {
                if ( stopProcessing ) return;
    
                System.out.println("ProcessingFile: " + i);
    
                // SwingUtilities makes sure code is executed in the event thread.
    
                SwingUtilities.invokeLater(new Runnable()
                {
                    public void run()
                    {
                        status.setText("Processing File: " + i);
                        status.paintImmediately(status.getBounds());
                    }
                });
    
                // simulate log running task
    
                try { Thread.sleep(1000); }
                catch (Exception e) {}
            }
    
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    status.setText("Finished Processing");
                    setButtons( true );
                }
            });
        }
    
        private void setButtons(boolean value)
        {
            eventThread.setEnabled( value );
            newThread.setEnabled( value );
        }
    
        public static void main(String[] args)
        {
            JFrame frame = new InvokeLaterTest();
            frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
            frame.pack();
            frame.setLocationRelativeTo( null );
            frame.show();
        }
    }
    
    import java.awt.*;
    导入java.awt.event.*;
    导入javax.swing.*;
    /*
    *关于长时间运行的任务和GUI更新的几个注意事项:
    *
    *1)所有GUI绘制应在事件线程中完成
    *2)在事件线程处理完成之前,不进行GUI绘制
    *
    *这意味着长时间运行的代码(数据库访问、文件处理…)
    *不应在事件线程中执行。可以为创建新线程
    *这些任务。
    *
    *大多数Swing方法都不是线程安全的。如果长时间运行的任务需要
    *要出于任何原因更新GUI,请单击SwingUtilities类
    *应用于向事件线程添加代码。
    *
    *有关更多信息,请参阅Swing教程“使用线程”
    * http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
    */
    公共类InvokeLaterTest扩展了JFrame
    实现ActionListener,可运行
    {
    JLabel状态;
    JButton事件线程;
    JButton新线程;
    按钮停止;
    螺纹;
    int i;
    布尔停止处理;
    公共调用器测试()
    {
    状态=新JLabel(“准备处理:”);
    状态。设置水平对齐(JLabel.CENTER);
    getContentPane().add(状态,BorderLayout.NORTH);
    eventThread=newjbutton(“在事件线程中启动”);
    addActionListener(这个);
    getContentPane().add(eventThread,BorderLayout.WEST);
    newThread=newjbutton(“在新线程中启动”);
    addActionListener(这个);
    getContentPane().add(newThread,BorderLayout.EAST);
    停止=新的JButton(“停止处理”);
    stop.addActionListener(this);
    getContentPane().add(停止,BorderLayout.SOUTH);
    }
    已执行的公共无效操作(操作事件e)
    {
    //代码正在事件线程中执行,因此不会更新标签
    //并且停止按钮将不会启用。
    如果(例如getSource()==eventThread)
    {
    停止处理=错误;
    run();
    }
    //代码正在新线程中执行,因此标签将被更新
    else if(例如getSource()==newThread)
    {
    停止处理=错误;
    线程=新线程(此);
    thread.start();
    }
    其他的
    {
    停止处理=真;
    status.setText(“处理已停止”);
    设置按钮(真);
    }
    }
    公开募捐
    {
    缩进(假);
    对于(i=1;i<10;i++)
    {
    如果(停止处理)返回;
    System.out.println(“处理文件:+i”);
    //SwingUtilities确保代码在事件线程中执行。
    SwingUtilities.invokeLater(新的Runnable()
    {
    公开募捐
    {
    status.setText(“处理文件:+i”);
    status.paintInstance(status.getBounds());
    }
    });
    //模拟日志运行任务
    试试{Thread.sleep(1000);}
    捕获(例外e){}
    }
    SwingUtilities.invokeLater(新的Runnable()
    {
    公开募捐
    {
    status.setText(“已完成处理”);
    设置按钮(真);
    }
    });
    }
    专用空心收进按钮(布尔值)
    {
    eventThread.setEnabled(值);
    newThread.setEnabled(值);
    }
    公共静态void main(字符串[]args)
    {
    JFrame frame=newinvokelatertest();
    frame.setDefaultCloseOperation(关闭时退出);
    frame.pack();
    frame.setLocationRelativeTo(空);
    frame.show();
    }
    }
    
    SwingWorker与上述逻辑类似,但:

  • 您需要禁用SwingWorker外部的按钮
  • 工作人员将为您创建线程并执行代码
  • 工作程序完成后,将调用工作程序的
    done()
    方法,以便您可以启用该按钮

  • 添加了completedTime变量以保存时间戳,如同操作完成时一样,每个事件都有生成时间,如果小于完成时间,则进行比较并返回
    JButton source = (JButton) e.getSource();
    
            if (source.isEnabled()) {
                Executors.newSingleThreadScheduledExecutor().execute(() -> {
    
                        source.setEnabled(false);
    
                        --your code here--
    
                        source.setEnabled(true);
                    }
                );
            }
        };
    
     long completedTime;
    
        mouseListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                    JButton source = (JButton) e.getSource();
                    long timeStamp = e.getWhen();
    
                       if (timeStamp < completedTime) {
    
                           System.out.println("returned");
                           return;
                       }
                   // source.setEnabled(false);
                    try {
                        RequestCommon.ctbCookie = jtf.getText();
                        System.out.println( RequestCommon.ctbCookie );
                        HttpURLConnection connection = HttpURLConnectionBuilder.getConnection(RequestCommon.login, RequestCommon.getCtb888Headers());
                        String connectionOuput = HttpURLConnectionBuilder.getConnectionOuput(connection);
                        System.out.println(connectionOuput);
                        new Player(new BufferedInputStream(new FileInputStream(new File("sounds/8.mp3")))).play();
                    } catch (IOException e1) {
                        e1.printStackTrace();
                    } catch (JavaLayerException e1) {
                        e1.printStackTrace();
                    }
                   // source.setEnabled(true);
                    completedTime = System.currentTimeMillis();
            }
        };