aspose file tools*
The moose likes Swing / AWT / SWT and the fly likes GUI update. Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "GUI update." Watch "GUI update." New topic
Author

GUI update.

Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
I need a little advice down here. I had a application here that I made, when I click the scan button, the antivirus should run and do the scanning (the antivirus runs on a thread here called threadRunner).

I want to "reset" the visibility of the jButtonScan to true ONLY after the thread finishes but how? Any ideas, how do I "inform" the GUI that the thread is not alive anymore / or has finished?

Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10355
    
    8

Try jButtonStop.setVisible(true); in a finally block of your run method


[How to ask questions] [Donate a pint, save a life!] [Onff-turn it on!]
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4541
    
    5

And wrap that in a SwingUtilities#invokeLater. Swing methods should be called only on the EDT.


luck, db
There are no new questions, but there may be new answers.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19693
    
  20

Even better, use a SwingWorker. Not only the statement Maneesh suggested, but also the call to jTextArea.append(s + "\n"); should be called on the EDT. Using a SwingWorker this can be done quite easily:
- let the current code run in the overridden doInBackground method, except
- call publish(s) instead of appending directly.
- override the process method to add all "chunks" to jTextArea (including the line break).
- override the done method to call Maneesh' statement.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10355
    
    8

Thanks Darryl. I must be slipping.

@Rob, Yes I forgot textArea.append is not thread safe. It really takes time getting used to after finding out that the documentation has been incorrect all these years.
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
Darryl Burke wrote:And wrap that in a SwingUtilities#invokeLater. Swing methods should be called only on the EDT.


What's a SwingMethod?

I've never used a Swingworker before. Can someone give a small example?
Maneesh Godbole
Saloon Keeper

Joined: Jul 26, 2007
Posts: 10355
    
    8

Aces Kok Ben wrote:
What's a SwingMethod?

Swing methods are methods which manipulate the state of any swing component. e.g. setVisible(), append()

I've never used a Swingworker before. Can someone give a small example?

http://java.sun.com/products/jfc/tsc/articles/threads/threads2.html
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4541
    
    5

Also http://download.oracle.com/javase/tutorial/uiswing/concurrency/index.html
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
Darryl Burke wrote:And wrap that in a SwingUtilities#invokeLater. Swing methods should be called only on the EDT.


Do you mean wrap the "threadRunner" in invokeLater?



Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4541
    
    5

You've been given two links to learning resources. Don't you think you should go through them?
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
Darryl Burke wrote:You've been given two links to learning resources. Don't you think you should go through them?


Yes, I will. (: Thanks alot. I will post in this thread again when I face problem.
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
Rob Spoor wrote:Even better, use a SwingWorker. Not only the statement Maneesh suggested, but also the call to jTextArea.append(s + "\n"); should be called on the EDT. Using a SwingWorker this can be done quite easily:
- let the current code run in the overridden doInBackground method, except
- call publish(s) instead of appending directly.
- override the process method to add all "chunks" to jTextArea (including the line break).
- override the done method to call Maneesh' statement.


I don't know if I'm doing this correctly. I created a private Class called Task that extends SwingWorker. Here's the class:



And in the actionPerformed of the Scan Button I edited:



I want to try if clicking the button will fire the Antivirus to run, and it did, the Antivirus did run, but I realised the Antivirus freezes after scanning the very first file. I don't understand. I used the Windows Task Manager to check the status of the antivirus engine - it is still running in the background. Why did it freeze?
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19693
    
  20

You're getting there, but the process method should contain code that needs to be executed on the EDT, and the reading should be done in doInBackground. Adding generic types you get this:
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
Rob Spoor wrote:You're getting there, but the process method should contain code that needs to be executed on the EDT, and the reading should be done in doInBackground. Adding generic types you get this..


There seemed to be an error on line 344, saying:

"Type safety: The method publish(Object...)belongs to the raw type SwingWorker. References to the generic type SwingWorker<T,V>, should be parameterized. "

Here's a screenshot:

http://i52.tinypic.com/2u56yqv.jpg

What does that mean?

EDITED:
I just try and edited the class name to "private class Task extends SwingWorker<void, void>", it didn't help either.
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4541
    
    5

http://download.oracle.com/javase/tutorial/java/generics/index.html
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44




There seemed to be some logic problems with my code. Initially I wanted the jButtonScan to be visible and jButtonStop to be NOT visible after the runAntivirus (which is a thread), had completed its scanning, however, the moment when I clicked the scan button, the jButtonScan immediately become visible again, even without waiting the thread, runAntivirus, which is inside "doInBackground" to finish. It seemed like the done() method was immediately called after the scan button was pressed. What happen?
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19693
    
  20

doInBackground immediately finishes after creating and starting the thread. done is then almost immediately executed. It will not wait for the thread to end.

Why did you use a new thread? doInBackground already is executed in a new thread. Move the code from the thread's run method to the doInBackground method and try again:
However, your code runs the risk of deadlock if the process' error stream fills up. Read When Runtime.exec() won't. An easy solution is to change the way the process is started:
Note: with ProcessBuilder you have to separate the arguments to the command from the command itself.
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
Mm, other than changing from Process to Processbuilder, how do I make the, jButton to "wait" for the process to be done? Since the done() method cannot be used in my situation. I'm running out of time
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19693
    
  20

Have you even tried my changes? I think not, or you would see that it would actually make the button enabling wait until the process was done.
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
And by the way, is it ok for my to pass in a String to the processBuilder class? I saw on the API that it could take a String. Previously what I did was I collate the command and the arguments together to form a String and run it in a process.
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
Omg. Now it's even worse, the Java cannot run the program. Here's the following error:

java.io.IOException: Cannot run program "mainbin/clamscan.exe --database="C:\Users\Aces\workspace\IT2529Proj\InfoSecurityProject\db" --verbose "C:\Fraps" ": CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessBuilder.start(Unknown Source)
at ui.Antivirus$Task.doInBackground(Antivirus.java:343)
at javax.swing.SwingWorker$1.call(Unknown Source)
at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at javax.swing.SwingWorker.run(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(Unknown Source)
at java.lang.ProcessImpl.start(Unknown Source)
... 9 more

I placed the Antivirus folder same level as where the src folder is. Before using ProcessBuilder everything was good. I tried changing the path of the exe file to it's absolute path:
"C:\Users\Aces\workspace\IT2529Proj\InfoSecurityProject\mainbin\clamscan.exe" but it doesn't seemed to work too.

The whole "cmd", which is a String, contains the name of the .exe file and the rest of its arguments.
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44


I went to read up the ProcessBuilder API and tried out the .directory() method. I added in pb.directory(new File("C:\\Users\\Aces\\workspace\\IT2529Proj\\InfoSecurityProject\\mainbin")); but the system cannot find the file too.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19693
    
  20

I think you may need glasses, because I already addressed that issue:
Rob Spoor wrote:Note: with ProcessBuilder you have to separate the arguments to the command from the command itself.

ProcessBuilder has two constructors; one takes a List<String>, the other one or more Strings using varargs. So you need to split off the arguments:
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
Sorry for being so foolish just now. I adjusted my codes the constructor takes in an arrayList of arguments instead of the hardcoded ones. However I still get the error that the file wasn't there. I'm sure the file (clamscan.exe) is there. I attached a screenshot of the directory:

http://i51.tinypic.com/xlxxcx.jpg
Ranganathan Kaliyur Mannar
Bartender

Joined: Oct 16, 2003
Posts: 1083
    
  10

I think that is a path issue. You can try giving the absolute path of the exe in the first argument. That should work.


Ranga.
SCJP 1.4, OCMJEA/SCEA 5.0.
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
Thanks to both Ranganathan and Rob, my button issue on my GUI is now fixed. I managed to fix the issue of the specified file error too. However I come to another problem which doesn't make any sense. My english isn't good so I will just post the screenshots:

This is the standard output of the clamscan.exe when I run the Antivirus on the command prompt:

http://i52.tinypic.com/34y2wzl.jpg

And this is the output when I run my Antivirus on my java GUI:

http://i51.tinypic.com/jz7i1d.png

As you can see, the output "LibClamAV Warning: ********, LibClamAV Warning: *** DON'T PANIC! Read http://www.clamav.net/support/faq ***" should appear before the Scan summary on the cmd, however on my GUI, it appears AFTER the scan summary. It doesn't make any sense. And also the word "Scan summary" isn't on the GUI text area at times. Sometimes it does, sometimes it doesn't.

I went to the processBuilder API to read around but I don't think it has something to do with it. Any ideas?
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19693
    
  20

You're not just missing those lines - you're missing every other line. As in: a line included, the next one isn't, then again, then again not, etc. The warning is also moved from the start to the end for some reason. This could be caused by the error stream redirection.

And I already found the reason. From your code:
That first call to input.readLine() reads a line from the output, but you only check the return value. The next line you read the next line, thereby not adding the first line. The solution is simple: use the well-known read-assign-check technique:
Aces Kok Ben
Ranch Hand

Joined: Apr 30, 2011
Posts: 44
I just want to thanks the people in JavaRanch here that helped me out with my GUI issue. I learnt more about background processing in Java programming which I haven't learnt in school. This is the first time I heard of Swingworker, processBuilder etc.

I had my project presentation today and most of the stuffs went smoothly. Thank you.
Darryl Burke
Bartender

Joined: May 03, 2008
Posts: 4541
    
    5

Aces Kok Ben wrote:I had my project presentation today and most of the stuffs went smoothly. Thank you.


 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: GUI update.