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