1

I want to build a JFrame able to run a background task every time a JButton was clicked.currently i am using a swing worker and it wont allow the task to be executed more than once.

How can I enable repetition task for SwingWorker with JButton click.

public class ScanFileFrame extends JFrame{

    JButton btnTicking;
    JLabel label1;

    ScanFileFrame(){

        JFrame jframe = new JFrame();
        jframe.setLayout(new FlowLayout());
        btnTicking = new JButton("Start Scanning Files");
        label1 = new JLabel("No File Scanned");

        btnTicking.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                worker.execute();

            }   
        });

        jframe.add(btnTicking);
        jframe.add(label1);

        jframe.setVisible(true);
        jframe.setSize(300,300);
    }

    SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {

        @Override
        protected Boolean doInBackground() throws Exception {

           // Simulate scan file
           System.out.println("scanning files ....");
           Thread.sleep(2000);

           return true;

        }

        //update jframe jlabel when background task finish
        protected void done() {
            label1.setText("Files Scanned");
            System.out.println("complete");
        }
    };

    public static void main(String[] args){
        ScanFileFrame f = new ScanFileFrame();

    }
}
Ridzuan Adris
  • 1,192
  • 2
  • 13
  • 32
  • 2
    *"using a swing worker and it wont allow the task to be executed more than once"* So create another one. What's the problem? For better help sooner, post an [MCVE](http://stackoverflow.com/help/mcve) (Minimal Complete Verifiable Example). – Andrew Thompson Oct 28 '14 at 02:16
  • oh, how do i implement it, because it will depend on user click. is there a way i can auto create a new one when user click.sorry i am new and have lot to learn – Ridzuan Adris Oct 28 '14 at 02:20
  • i will edit my code.. – Ridzuan Adris Oct 28 '14 at 02:22
  • Yes, as @AndrewThompson mentions, you want to create a new SwingWorker each time one is needed, and then run it. It's kind of hard to guess what is not working for you based on the limited information that you've posted so far. – Hovercraft Full Of Eels Oct 28 '14 at 02:40

1 Answers1

5

currently i am using a swing worker and it wont allow the task to be executed more than once.

This is not an issue since you would just construct a new SwingWorker and run it within your JButton's ActionListener. As far as I can tell, this is the solution to your question as it is currently written. If you need a more detailed answer, then you'll want to provide more detail in your question.


Edit You state:

but i have no idea how to reinvent the swingworker everytime the user click the scan button.

How do you "reinvent" any object? By creating a new instance, here a new MySwingWorker, and then call execute on it.


e.g.,

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;

import javax.swing.*;

public class ScanFileFrame {
   private FileScanAction fileScanAction = new FileScanAction("Scan Files", KeyEvent.VK_S);
   private JButton btnTicking = new JButton(fileScanAction);
   private JLabel label1;
   private MyFileScanWorker worker;

   ScanFileFrame() {

      JFrame jframe = new JFrame();
      jframe.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      jframe.setLayout(new FlowLayout());
      label1 = new JLabel("       No File Scanned       ", SwingConstants.CENTER);

      jframe.add(btnTicking);
      jframe.add(label1);
      jframe.pack();
      jframe.setLocationByPlatform(true);
      jframe.setVisible(true);

   }

   @SuppressWarnings("serial")
   private class FileScanAction extends AbstractAction {
      public FileScanAction(String name, int mnemonic) {
         super(name);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         label1.setText("Scanning Files");
         fileScanAction.setEnabled(false);
         worker = new MyFileScanWorker();
         worker.addPropertyChangeListener(new WorkerListener());
         worker.execute();
      }
   }

   private class WorkerListener implements PropertyChangeListener {
      @Override
      public void propertyChange(PropertyChangeEvent pcEvt) {
         if (pcEvt.getNewValue() == SwingWorker.StateValue.DONE) {
            fileScanAction.setEnabled(true);
            try {
               boolean success = worker.get();
               String text = success ? "Scanning Successful" : "Scanning Error";
               label1.setText(text);
            } catch (InterruptedException | ExecutionException e) {
               e.printStackTrace();
            }
         }
      }
   }

   private class MyFileScanWorker extends SwingWorker<Boolean, Void> {

      @Override
      protected Boolean doInBackground() throws Exception {
         // Simulate scan file
         Thread.sleep(2000);

         // have it work successfully 2/3 of the time.
         if (Math.random() > 0.3333) {
            return true;
         } else {
            return false;
         }
      }
   };

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            new ScanFileFrame();
         }
      });
   }
}

Note that you always want to call get() on your SwingWorker after it has completed, even if it returns null, so that you can trap any exceptions that might have occurred during the SwingWorker's run.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • sorry for the time, i have edited and posted a simplified code. basically it will call a scanFile method and run in background from button click. but i have no idea how to reinvent the swingworker everytime the user click the scan button. – Ridzuan Adris Oct 28 '14 at 02:50
  • so in jbutton actionlistener i will be need to edit worker.execute() is it not? :) – Ridzuan Adris Oct 28 '14 at 02:55
  • i noticed create a new instance for worker will create new jframe each time the button was clicked because of the nature of jframe structure. is there any way we can alter the code to prevent it from running new jframe.. – Ridzuan Adris Oct 28 '14 at 03:43
  • No idea what you mean. The code you've posted and that i've posted does no such thing. – Hovercraft Full Of Eels Oct 28 '14 at 03:50