单击后禁用JButton并在完成它的工作时启用它

时间:2017-11-20 15:55:44

标签: java swing

我有一个带有actionListener的JButton,当我多次点击它时,它会像我点击一样多次完成它的工作,下面是我的代码:

   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);

我想要的是无论我在工作期间点击多少次,它都不会再次执行。当工作完成后,如果我再次点击,工作将再次运行。我不知道该怎么做,请告诉我你是否知道,谢谢!

4 个答案:

答案 0 :(得分:5)

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

最简单的方法是使用SwingWorker。您可以在启动worker之前禁用该按钮,然后该worker调用了done()方法,您可以启用该按钮。

阅读Concurrency in Swing上Swing教程中的部分,了解有关EDT的更多信息以及Swing worker的工作示例。

编辑:

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

以下是我在SwingWorker存在之前编写的一些旧代码。 “在新线程中启动”按钮的基本逻辑是:

  1. 禁用按钮,以便在处理过程中无法单击
  2. 通过循环10次并暂停
  3. 来模拟长时间运行的任务
  4. 启用按钮,以便再次完成任务
  5. 以下是代码:

    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();
        }
    }
    

    SwingWorker与上述逻辑类似,但是:

    1. 您需要禁用SwingWorker外的按钮
    2. 工作人员将为您创建线程并执行代码
    3. 当worker完成时,调用worker的done()方法,以便启用该按钮。

答案 1 :(得分:0)

我确实应该使用if并在执行代码之前检查按钮是否已启用。

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

我希望我帮助你。 :)

答案 2 :(得分:-1)

RewriteCond %{HTTPS} off
RewriteCond %{HTTP_HOST} example\.com$ [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L,NE]

答案 3 :(得分:-1)

添加了一个completedTime变量来保存时间戳,就像操作完成时一样,每个事件都有生成时间,比较并返回,如果它小于完成时间

 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();
        }
    };