Not Responding-While copying files in SWT not in jFace - java

I have to display the progress bar while copying files. My code is displaying the progress bar. window is not responding while copying files.
Here my code:
Thread t = new Thread(new Runnable() {
#Override
public void run() {
try {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
try {
SetupDir = new File(SWT_Second.currentDir.getAbsolutePath().concat(File.separator).concat("setup"));
count=numberOfFiles(SetupDir);
logFileHandle.writeBytes("\nTotal Number of Files.... "+count);
System.out.println("NEW COUNT"+count);
copyFiles(SetupDir,dartBaseDir);
logFileHandle.writeBytes("copy over..: ");
copy_next_button.setEnabled(true);
actualCopyFlag=true;
} catch (IOException e) {
e.printStackTrace();
};
}
});
} catch (Exception ex) {
ex.printStackTrace();
System.exit(0);
}
}
});
t.start();
Method for copying files:
public static void copyFiles(final File srcDir,File destDir) throws IOException{
String mkDir= null;
File mkDir1=null;
String cpDir= null;
File cpDir1=null;
pbar.setMinimum(0);
pbar.setMaximum(count);
for (File f : srcDir.listFiles()) {
System.out.println("Copying for file : " + f.getAbsolutePath());
if(f.isDirectory())
{
System.out.println("INSIDE DIRECTORY LOOP");
System.out.println("It is a directory"+f.getName());
cpDir=srcDir.getAbsolutePath().concat(File.separator).concat(f.getName());
cpDir1=new File(cpDir);
System.out.println("cpDir: "+cpDir);
mkDir = destDir.getAbsolutePath().concat(File.separator).concat(f.getName());
mkDir1 = new File(mkDir);
System.out.println("mkDir : "+mkDir);
if( !mkDir1.exists() ) {
mkDir1.mkdir();
}
copyFiles(cpDir1, mkDir1);
}
else
{ pb++;
System.out.println("It is simple a file .....");
File newFile = new File(destDir.getAbsolutePath().concat(File.separator).concat(f.getName()));
System.out.println("newFile: "+newFile);
Files.copy(Paths.get(f.getAbsolutePath()), Paths.get(newFile.getAbsolutePath()), StandardCopyOption.COPY_ATTRIBUTES);
pbar.setSelection (pb+1);
int x=pb+1;
System.out.println("bar.setSelection (j+1): "+x );
System.out.println("copy done for "+f.getAbsoluteFile() +" to "+newFile);
}
System.out.println("Copy done for : " + f.getAbsoluteFile());
}
}
}
While copying files, the shell window is automatically not responding.
Help would appreciate..!!

Your call to Display.getDefault().asyncExec is running your entire copy files operation in the user interface thread which causes it to become unresponsive.
Instead you should just call asyncExec each time you want to update the user interface. So
... copy file code in background thread
Display.getDefault().asyncExec(new Runnable() {
public void run() {
pbar.setSelection (pb+1);
}
});

Related

Ant task goes normal in the main method, but stops after definite line during Ant execution

Does anybody know, why such ant task:
public void execute() {
Timer timer = new Timer();
TimerTask action = new TimerTask() {
#SuppressWarnings("ResultOfMethodCallIgnored")
public void run() {
String urlsForCheckPath = arachniBinPath + "urls.txt";
List<String> urlsForCheck;
try {
urlsForCheck = FileUtils.readLines(new File(urlsForCheckPath));
if (urlsForCheck != null) {
for (String urlForCheck : urlsForCheck) {
new File(arachniLogPath).delete();
clearTemporary(urlForCheck);//if something remains after exceptions
logger.info(urlForCheck + " previous log and possibly remaining temporary files deleted.");
checkURL(urlForCheck);
urlForCheck = urlForCheck.replace("/", "-");
convertAndSend(urlForCheck);
clearTemporary(urlForCheck);
logger.info(urlForCheck + " temporary files deleted.");
}
}
} catch (Exception e) {
log(e);
}
}
};
timer.schedule(action, delayBeforeStart);
}
goes normal in the main method, but stops after
logger.info(urlForCheck + " previous log and possibly remaining temporary files deleted.");
without exceptions during execution via ant? How it can be fixed?
I think you should read this answer.
Java: Wait for TimerTask to complete before continuing execution
Small example:
protected final Timer timer = new Timer();
public void execute() {
CountDownLatch latch = new CountDownLatch(1);
timer.schedule(new TimerTask() {
public void run() {
}
}, delayBeforeStart);
try {
latch.await();
} catch (InterruptedException e) {
log(e);
}
timer.cancel();
}

How to rebuild method to a thread

how can I rebuild my method:
public class PDFCheck {
public static void testAllFontsAreEmbedded(PDFDocument pdf) throws PDFDocumentException {
for (PDFFont font : pdf.listFonts()) {
if (!font.isEmbedded()) {
errorMessageBuffer.append("font not embedded: " + font.getName() + "\n");
fontError = "font error";
}
}
into a Thread like that here:?
public class Task1 implements Runnable {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
................
................
................
................
}
}
}
In main I will do like this:
Thread t1 = new Thread(new Task1());
t1.start();
t1.interrupt();
I want to do that because I've developed a pdf check tool and a stop button should stop the "font chek" (see above code snippet) when a pdf is too large and takes too long to be checked.
I tried this to build a constructor, but the constructor shows a lot of error messages:
public void run() {
while (!Thread.currentThread().isInterrupted()) {
public static void testAllFontsAreEmbedded(PDFDocument pdf) throws PDFDocumentException {
for (PDFFont font : pdf.listFonts()) {
if (!font.isEmbedded()) {
fontError = "font error" + " | ";
} else {
fontError = "";
}
}
System.out.println("läuft");
}
}
}
UPDATE: I integrate finally a Thread in this method. The Proble now is that the method just choose all the time the first pdf file of the path...Is my while statement at a wrong position?
new Thread() {
#Override
public void run() {
String directory;
directory = "C:\\Users\\Tommy\\Desktop\\pdf";
File inputFiles = new File(directory);
CopyOfSettingsGui.this.running = true;
for (File file : inputFiles.listFiles()) {
if (file.isFile()) {
if (file.getName().endsWith((".pdf"))) {
while (CopyOfSettingsGui.this.running) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.print(file.getName() + "\n");
}
return;
}
}
}
}
}.start();
You can pass the pdf as described in the answer of Conffusion, but if you want to use interrupt() you have to make your thread 'interuptable' This method don't stops the thread unless your thread is invoking methods that throw 'Interrupted Exception' or checks the 'interrupted flag'. So you have to invoke ´Thread.interrupted()´ in every iteration.
public void run() {
for (PDFFont font : pdf.listFonts()) {
if (Thread.interrupted()){
return;
}
...
}
}
Alternatively, you can set a member variable to stop the thread:
class PDFCheckThread extends Thread {
private boolean stop;
public PDFCheckThread(PDFDocument pdf) {
this.pdf = pdf;
}
public void setStopFlag() {
stop = true;
}
public void run() {
for (PDFFont font : pdf.listFonts()) {
if(stop) {
return;
}
...
}
}
}
You have to pass the PDF to the Task1 constructor and store it in a local variable (within Task1. From within the run() method you can access the PDF document:
public class Task1 implements Runnable {
private PDFDocument pdf;
public Task1 (PDFDocument pdf) {
this.pdf=pdf;
}
public void run() {
for (PDFFont font : pdf.listFonts()) {
if (!font.isEmbedded()) {
fontError = "font error" + " | ";
} else {
fontError = "";
}
}
System.out.println("läuft");
}
}
}
To launch the thread:
Thread t1 = new Thread(new Task1(myPDFInstance));
t1.start();
t1.interrupt();

Interrupting a thread doesn't work after pushing a (applet) button

I made a simple programm to let java play some .mp3 files.
Using JLayer to get this right.
The problem is that i can't interrupt my player after pushing a button.
my code in actionperformed:
class MyThread extends Thread {
#Override
public void run() {
try {
File file = new File(source);
FileInputStream fis = new FileInputStream(file);
BufferedInputStream bis = new BufferedInputStream(fis);
try {
Thread.sleep(1);
try {
Player player = new Player(bis);
player.play();
} catch (JavaLayerException ex) {
}
} catch (InterruptedException e) {
System.out.println("Came");
}
} catch (IOException e) {
lab2.setText("error, is the pathway correct?");
}
}
}
MyThread mythread = new MyThread();
if (event.getSource() == input) {
source = input.getText();
source = source.replace("\\", "\\\\");
lab1.setText(source);
}
if (event.getSource() == but1) {
mythread.start();
}
if (event.getSource() == but2) {
but2.setLabel("stop");
mythread.interrupt();
but2.setLabel("stopped");
}
}
}
When I add the mythread.interrupt(); directly behind the interrupt works and my system gives me the "came" output.
But if I use my button called input, it wont work.
Seems that player class doesnt have a stop method, but you can try with AdvancedPlayer:
http://www.javazoom.net/javalayer/docs/docs1.0/javazoom/jl/player/advanced/AdvancedPlayer.html
and the stop() method.

Open image file nullpointer exception

I have to change the icon of a label every 2 seconds. I have 3 pictures in src folder. To change them i use a thread. The code i wrote:
private Thread t;
private int indexIcon;
public ImageIcon[] icons = {new ImageIcon(this.getClass().getResource("orange.jpg")),
new
ImageIcon(this.getClass().getResource("cosmote.jpg")), new
ImageIcon(this.getClass().getResource("vodafone.jpg"))};
public void run() {
while (true) {
try {
Thread.sleep(2000);
if (Thread.interrupted()) {
return;
}
indexIcon++;
if (indexIcon > 2) {
indexIcon = 0;
}
jLabel8.setIcon(icons[indexIcon]);
} catch (InterruptedException ex) {
Logger.getLogger(CarteDeTelefonGUI.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
And in the class constructor:
t = new Thread(this);
t.start();
It works fine, but the problem is that when i run the program on a different computer it doesn't read the images, i get a nullpointer exception.
How could i solve this problem?

Thread.join does not seem to work in my code; am I using it right?

I have a class Automator that can automate a user. I am specifically having problems setting the system clipboard in windows. The Automator class makes use of the ClipSetThread class, which is a thread that sets the system clipboard. A instance of ClipSetThread takes as input a thread, that if null, it joins with (waits for it to complete).
I feel that I am not calling ClipSetThread right because I still have the errors I have had before in its reliability; prior to the ClipSetThread. This code does not throw any errors when it runs, it works about 2/3 of the time though. Other times it will print 1134, _234, or etc. It seems that the threads are not joining (waiting for) each other, or get skipped.
Code:
import java.awt.AWTException;
import java.awt.Robot;
import java.awt.event.KeyEvent;
import org.jnativehook.GlobalScreen;
import org.jnativehook.NativeHookException;
import org.jnativehook.mouse.NativeMouseEvent;
import org.jnativehook.mouse.NativeMouseInputListener;
public class Automator extends Thread implements NativeMouseInputListener
{
Robot rob = null;
TheAppClass theApp = null;
ClipSetThread lastClipSet = null;
boolean doit = false;
boolean settingClip = false;
public void run()
{
try // to make the Global hook
{
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex){theApp.updateOutput("No Global Keyboard or Mouse Hook");return;}
try // to create a robot (can simulate user input such as mouse and keyboard input)
{
rob = new Robot();
}
catch (AWTException e1) {theApp.updateOutput("The Robot could not be created");return;}
while(true) {}
}
public void setApp(TheAppClass app)
{
theApp = app;
theApp.updateOutput("Succesfully started automator");
}
public void setClip(String arg)
{
ClipSetThread set = new ClipSetThread(theApp, lastClipSet);
lastClipSet = set;
set.setClip(arg);
}
public void DOit()
{
theApp.updateOutput("Starting");
pasteAtCursorLocation("1");
tab(1);
pasteAtCursorLocation("2");
tab(1);
pasteAtCursorLocation("3");
tab(1);
pasteAtCursorLocation("4");
tab(1);
theApp.updateOutput("Complete");
}
public void nativeMouseReleased(NativeMouseEvent e)
{
//System.out.println("Mouse Released: " + e.getButton());
if(doit)
{
DOit();
doit = false;
}
}
public void pasteAtCursorLocation(String text)
{
setClip(text);
rob.keyPress(KeyEvent.VK_CONTROL);
rob.keyPress(KeyEvent.VK_V);
rob.keyRelease(KeyEvent.VK_V);
rob.keyRelease(KeyEvent.VK_CONTROL);
theApp.updateOutput("Simulated Paste");
}
public void tab(int numTimes)
{
while(numTimes > 0)
{
rob.keyPress(KeyEvent.VK_TAB);
rob.keyRelease(KeyEvent.VK_TAB);
numTimes--;
theApp.updateOutput("Simulated Tab");
}
}
// Unimplemented
public void nativeMouseClicked(NativeMouseEvent arg0) {}
public void nativeMousePressed(NativeMouseEvent arg0) {}
public void nativeMouseDragged(NativeMouseEvent arg0) {}
public void nativeMouseMoved(NativeMouseEvent arg0) {}
}
ClipSetThread:
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
public class ClipSetThread extends Thread
{
Clipboard sysClip = null;
TheAppClass theApp = null;
public ClipSetThread(TheAppClass app, Thread waitFor)
{
theApp = app;
sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
if(waitFor != null)
{try {waitFor.join();}catch (InterruptedException e) {}}
}
public void setClip(String arg)
{
// Two strings that will hopefully never be on the clipboard
String checkStr1 = "9999999999999";
String checkStr2 = "99999999999999";
// When we read in the clipboard we want to see if we change these strings from the ones they
// will never be, if they do change we read the clipboard successfully
String clipBoardTextBefore = checkStr1;
String clipBoardTextAfter = checkStr2;
// First get a copy of the current system clipboard text
while(true)
{
try
{
Transferable contents = sysClip.getContents(null);
clipBoardTextBefore = (String)contents.getTransferData(DataFlavor.stringFlavor);
}
catch(Exception e)
{
try {Thread.sleep(20);} catch (InterruptedException e1) {}
continue;
}
break;
}
// If we failed to change the string it means we failed to read the text
if(clipBoardTextBefore.equals(checkStr1))
theApp.updateOutput("Could NOT get sysClip text");
else
{
// If we didn't failed to get the current text try to change it
while(true)
{
try{sysClip.setContents(new StringSelection(arg), null);}
catch(Exception e)
{
try {Thread.sleep(20);} catch (InterruptedException e1) {}
continue;
}
break;
}
// Now again check to see the clipboard text
while(true)
{
try
{
Transferable contents = sysClip.getContents(null);
clipBoardTextAfter = (String)contents.getTransferData(DataFlavor.stringFlavor);
}
catch(Exception e)
{
try {Thread.sleep(20);} catch (InterruptedException e1) {}
continue;
}
break;
}
// If we failed to read the clipboard text
if(clipBoardTextAfter.equals(checkStr2))
theApp.updateOutput("Could NOT check if sysClip update was successful");
else
{ // We re-read the clipboard text, see if it changed from the original clipboard text
if(clipBoardTextAfter.equals(checkStr1))
theApp.updateOutput("Could NOT successfully set clipboard text");
else
theApp.updateOutput("Set Clipboard Text:" + arg + "\n");
}
}
}
}
So, firstly, you never call start on the ClipSetThread. You should also check to see if the thread is still alive before joining it.
public class ClipSetThread extends Thread {
Clipboard sysClip = null;
TheAppClass theApp = null;
private String toClipboard;
public ClipSetThread(TheAppClass app, Thread waitFor, String toClipBoard) {
theApp = app;
sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
this.toClipboard = toClipBoard;
// !! Check to see if the thread is also alive before trying to join with it...
if (waitFor != null && waitFor.isAlive()) {
try {
waitFor.join();
} catch (InterruptedException e) {
}
}
}
// You should really put your logic into the `run` method in order to allow
// the code to actually run in a separate thread...otherwise there is no
// point in using a thread....
#Override
public void run() {
// Two strings that will hopefully never be on the clipboard
String checkStr1 = "9999999999999";
String checkStr2 = "99999999999999";
// When we read in the clipboard we want to see if we change these strings from the ones they
// will never be, if they do change we read the clipboard successfully
String clipBoardTextBefore = checkStr1;
String clipBoardTextAfter = checkStr2;
// First get a copy of the current system clipboard text
while (true) {
try {
Transferable contents = sysClip.getContents(null);
clipBoardTextBefore = (String) contents.getTransferData(DataFlavor.stringFlavor);
} catch (Exception e) {
try {
Thread.sleep(20);
} catch (InterruptedException e1) {
}
continue;
}
break;
}
// If we failed to change the string it means we failed to read the text
if (clipBoardTextBefore.equals(checkStr1)) {
theApp.updateOutput("Could NOT get sysClip text");
} else {
// If we didn't failed to get the current text try to change it
while (true) {
try {
sysClip.setContents(new StringSelection(toClipboard), null);
} catch (Exception e) {
try {
Thread.sleep(20);
} catch (InterruptedException e1) {
}
continue;
}
break;
}
// Now again check to see the clipboard text
while (true) {
try {
Transferable contents = sysClip.getContents(null);
clipBoardTextAfter = (String) contents.getTransferData(DataFlavor.stringFlavor);
} catch (Exception e) {
try {
Thread.sleep(20);
} catch (InterruptedException e1) {
}
continue;
}
break;
}
// If we failed to read the clipboard text
if (clipBoardTextAfter.equals(checkStr2)) {
theApp.updateOutput("Could NOT check if sysClip update was successful");
} else { // We re-read the clipboard text, see if it changed from the original clipboard text
if (clipBoardTextAfter.equals(checkStr1)) {
theApp.updateOutput("Could NOT successfully set clipboard text");
} else {
theApp.updateOutput("Set Clipboard Text:" + toClipboard + "\n");
}
}
}
}
}
As per our previous converstaion, it's dangerous to use while (true) {}, it's also wasteful, as it will consume CPU cycles unnecessarily...
public class Automator extends Thread implements NativeMouseInputListener {
// A "locking" object...
private static final Object WAIT_LOCK = new Object();
Robot rob = null;
TheAppClass theApp = null;
ClipSetThread lastClipSet = null;
boolean doit = false;
boolean settingClip = false;
public void run() {
try // to make the Global hook
{
GlobalScreen.registerNativeHook();
} catch (NativeHookException ex) {
theApp.updateOutput("No Global Keyboard or Mouse Hook");
return;
}
try // to create a robot (can simulate user input such as mouse and keyboard input)
{
rob = new Robot();
} catch (AWTException e1) {
theApp.updateOutput("The Robot could not be created");
return;
}
// This is wasteful...
// while (true) {
// }
// Locks do not consume CPU cycles while in the wait state...
synchronized (WAIT_LOCK) {
try {
WAIT_LOCK.wait();
} catch (Exception exp) {
}
}
}
public void dispose() {
// Tell the thread it can terminate...
synchronized (WAIT_LOCK) {
WAIT_LOCK.notify();
}
// This will STOP the current thread (which called this method)
// while the lastClipSet finishes...
if (lastClipSet != null && lastClipSet.isAlive()) {
lastClipSet.join();
}
}
public void setClip(String arg) {
ClipSetThread set = new ClipSetThread(theApp, lastClipSet, arg);
lastClipSet = set;
// You MUST START the thread...
set.start();
}
/*...*/
}
Updated
This code could produce a infinite loop. What happens if the clipboard does not contain a String value??
while(true)
{
try
{
Transferable contents = sysClip.getContents(null);
clipBoardTextBefore = (String)contents.getTransferData(DataFlavor.stringFlavor);
}
catch(Exception e)
{
try {Thread.sleep(20);} catch (InterruptedException e1) {}
continue;
}
break;
}
You tend to do this a lot. I might suggest that you provide some kind of "escape" mechanism to allow it to fail after a number of retries...
boolean successful = false;
int retries = 0;
while (!successful && retries < 20) {
{
try
{
Transferable contents = sysClip.getContents(null);
clipBoardTextBefore = (String)contents.getTransferData(DataFlavor.stringFlavor);
successful = true;
}
catch(Exception e)
{
retries++;
try {Thread.sleep(20);} catch (InterruptedException e1) {}
}
}
Updated with working example
Okay, that was fun. I've put together a (simple) working example. You will want to open a text editor of some kind. When you run the program, you have 5 seconds to make it active ;)
The only basic change I've made is I set added a auto delay between events of 250 milliseconds (see rob.setAutoDelay(250).
Now, you could also place a delay between each key event as well, using Robot#delay, but that's up to you
public class Engine extends Thread {
private Robot rob = null;
private PasteThread lastClipSet = null;
public void setClip(String arg) {
if (lastClipSet != null && lastClipSet.isAlive()) {
try {
lastClipSet.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
PasteThread set = new PasteThread(arg);
lastClipSet = set;
lastClipSet.start();
}
public void pasteAtCursorLocation(String text) {
System.out.println("Paste " + text);
setClip(text);
rob.keyPress(KeyEvent.VK_CONTROL);
rob.keyPress(KeyEvent.VK_V);
rob.keyRelease(KeyEvent.VK_V);
rob.keyRelease(KeyEvent.VK_CONTROL);
}
public Engine() throws AWTException {
rob = new Robot();
rob.setAutoDelay(250);
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
}
pasteAtCursorLocation("This is a simple test, thanks for watching!");
}
public static void main(String[] args) {
try {
new Engine();
} catch (AWTException ex) {
Logger.getLogger(Engine.class.getName()).log(Level.SEVERE, null, ex);
}
}
public class PasteThread extends Thread {
private String toPaste;
public PasteThread(String value) {
toPaste = value;
}
#Override
public void run() {
Clipboard sysClip = Toolkit.getDefaultToolkit().getSystemClipboard();
System.out.println("Current clipboard contents = " + getClipboardContents(sysClip));
sysClip.setContents(new StringSelection(toPaste), null);
System.out.println("New clipboard contents = " + getClipboardContents(sysClip));
}
public String getClipboardContents(Clipboard clipboard) {
String value = null;
boolean successful = false;
int retries = 0;
while (!successful && retries < 20) {
Transferable contents = clipboard.getContents(null);
if (contents.isDataFlavorSupported(DataFlavor.stringFlavor)) {
try {
value = (String) contents.getTransferData(DataFlavor.stringFlavor);
successful = true;
} catch (Exception exp) {
retries++;
exp.printStackTrace();
}
} else {
retries++;
}
}
System.out.println(successful + "/" + retries);
return value;
}
}
}
Could you please try to repeat the Paste action with a sleep 1 second in between
public void pasteAtCursorLocation(String text)
{
setClip(text);
rob.keyPress(KeyEvent.VK_CONTROL);
rob.keyPress(KeyEvent.VK_V);
rob.keyRelease(KeyEvent.VK_V);
rob.keyRelease(KeyEvent.VK_CONTROL);
theApp.updateOutput("Simulated Paste");
// put in a sleep 1 second here
rob.keyPress(KeyEvent.VK_CONTROL);
rob.keyPress(KeyEvent.VK_V);
rob.keyRelease(KeyEvent.VK_V);
rob.keyRelease(KeyEvent.VK_CONTROL);
theApp.updateOutput("Simulated Paste");
}
It could be that pasting 2x is giving different results. The reason for this strange behavior could the way Windows manages the clipboard. If pasting 2x the clipboard is giving different result then you know that the root cause for this strange behavior is not to find in your code but how Java and Windows work together.

Categories