Permlink Replies: 17 - Pages: 2 [ 1 2 | Next ] - Last Post: 16 Nov 18, 14:38 Last Post By: davidekholm Threads: [ Previous | Next ]
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
New support class for long running tasks
Posted: 29 Oct 18, 18:20
  Click to reply to this thread Reply
jAlbum 17 (released today) has a new support class that takes a lot of work from developers who have tasks that take a long time to complete. With long running tasks you shouldn't lock the UI but instead run the task on a background thread, but you should also inform the user that a slow task is underway and allow the user to abort the task. All this (but the slow work itself) can now be handled by the new MonitoredWorkQueue class.

Here's a usage example:
MonitoredWorkQueue workQueue = new MonitoredWorkQueue(window, "Convert link to copy");
for (AlbumObject ao : selected) {
    workQueue.submit(() -> {
        File src = LinkFile.targetOf(ao.getFile());
        workQueue.setMessage(ao.getName());
        File target = new File(currentFolder.getFile(), ao.getFile().getName());
        if (src.isDirectory()) {
            target.mkdir();
        }
        IO.copyFile(src, target);
    });
}
workQueue.awaitCompletion();
RobM

Posts: 3,808
Registered: 4-Aug-2006
Re: New support class for long running tasks
Posted: 29 Oct 18, 21:12   in response to: davidekholm in response to: davidekholm
  Click to reply to this thread Reply
Should there really be two closing ')' on the first line?

No (blush). I edited the code a bit to make it clearer, but didn't let the compiler have a go at it. Now fixed

What is 'currentWindow'?

Just pseudo code. You can replace with window

Can this be used in external tools, if so can you give an example without Lambda expressions - they are not supported in Beanshell, are they?

True. BeanShell is soo outdated and unfortunately doesn't support Lambda expressions. Given that you've imported se.datadosen.util.Task , Lambda expressions like
() -> { ... }
can be replaced with the following
new Task() { public void call() { ... } }
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: New support class for long running tasks
Posted: 30 Oct 18, 11:54   in response to: RobM in response to: RobM
  Click to reply to this thread Reply
Sorry I accidentally edited instead of referring to your post Rob
RobM

Posts: 3,808
Registered: 4-Aug-2006
Re: New support class for long running tasks
Posted: 30 Oct 18, 11:58   in response to: davidekholm in response to: davidekholm
  Click to reply to this thread Reply
davidekholm wrote:
Sorry I accidentally edited instead of referring to your post Rob
Actually, that makes it easier for me to follow :)
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: New support class for long running tasks
Posted: 30 Oct 18, 12:12   in response to: RobM in response to: RobM
  Click to reply to this thread Reply
My number one wish for Java is to get an updated equivalent to BeanShell. I can't imagine that this excellent way of scripting in Java should only be of use for jAlbum skins. Lambda expressions are such an excellent and important addition to Java so it's a shame we can't use it from within BeanShell. It's not just "syntactic sugar", i.e. a shorthand notion, but these expressions actually execute super fast inside the JVM. There is no object creation involved when a Lambda expression is encountered, even though a Lambda expression always maps to a Java interface for the sake of type correctness. What Lambda expressions essentially does is to allow you to treat code as data. That opens up a world of possibilities (just google "Functional programming")
RobM

Posts: 3,808
Registered: 4-Aug-2006
Re: New support class for long running tasks
Posted: 30 Oct 18, 21:03   in response to: davidekholm in response to: davidekholm
  Click to reply to this thread Reply
I have it working :)

But I have more questions now.

The progress window is a fixed size and doesn't fit all of the text I want to display. How do I resize the window, or even better can I add text above the progress bar?

The progress bar is shown as 'full', as though already completed rather than incrementally increasing. I thought this might be my particular usage as I have a process with a 'waitFor()', but removing that waitFor made no difference.

My code is
import net.jalbum.util.MonitoredWorkQueue;
import net.jalbum.util.Task;
 
MonitoredWorkQueue workQueue = new MonitoredWorkQueue(window, ao.getName() + " being processed");
	workQueue.submit(new Task() { public void call() {
 
		//Start a process for the ffmpeg command
		Runtime rt = Runtime.getRuntime();
                p = rt.exec(new String[]{ffmpeg, …});
…
		int exitVal = p.waitFor();
…
});
workQueue.awaitCompletion();


I'm liking it, much better for these long ffmpeg scripts as before it was difficult to provide proper feedback on what was actually being processed.
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: New support class for long running tasks
Posted: 30 Oct 18, 21:41   in response to: RobM in response to: RobM
  Click to reply to this thread Reply
Did you try setMessage()? That message is supposed to be changed as your task moves along. The progress bar isn't actually "full", it has this striped animation which is supposed to indicate an indeterminate task, i.e. a task where we don't know/tell how long it will be running. I might extend this class to allow for indicating real progress for those who actually know just how far they've progressed.

For a wider dialog, call setMessage with an empty string with enough spaces to fit the widest string you need before you call awaitCompletion (it is awaitCompletion that triggers the dialog creation)
RobM

Posts: 3,808
Registered: 4-Aug-2006
Re: New support class for long running tasks
Posted: 30 Oct 18, 21:47   in response to: davidekholm in response to: davidekholm
  Click to reply to this thread Reply
davidekholm wrote:
My number one wish for Java is to get an updated equivalent to BeanShell. I can't imagine that this excellent way of scripting in Java should only be of use for jAlbum skins.
Given I don't know what I'm talking about - the dangers of searching the net - what about Groovy?
What Lambda expressions essentially does is to allow you to treat code as data. That opens up a world of possibilities (just google "Functional programming")
Sadly, most of it goes over my head. Ignoring my advanced years, which seems to be inversely proportional to my coding skill - I'm getting slower and have to keep referring to previously written stuff - I have always favoured the 'Show me' method of learning. Examples trump API documents.
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: New support class for long running tasks
Posted: 30 Oct 18, 21:53   in response to: davidekholm in response to: davidekholm
  Click to reply to this thread Reply
It's usually the responsibility of the task to check the isAborted() state regularly and throw an OperationAbortedException to abort if user has clicked the abort button on the dialog, but tasks that perform IO operations sensitive to being interrupted should also respond, like the call to p.waitFor() that you perform.

You can also submit a series of, in themselves, short lived tasks to the queue and then call awaitCompletion(). In such cases, there is no need for each submitted task to check the isAborted() state or to respond to interruption. As soon as the user aborts the dialog, then all not-yet executed tasks will be discarded.
RobM

Posts: 3,808
Registered: 4-Aug-2006
Re: New support class for long running tasks
Posted: 30 Oct 18, 22:13   in response to: davidekholm in response to: davidekholm
  Click to reply to this thread Reply
davidekholm wrote:
Did you try setMessage()? That message is supposed to be changed as your task moves along. The progress bar isn't actually "full", it has this striped animation which is supposed to indicate an indeterminate task, i.e. a task where we don't know/tell how long it will be running. I might extend this class to allow for indicating real progress for those who actually know just how far they've progressed.

For a wider dialog, call setMessage with an empty string with enough spaces to fit the widest string you need before you call awaitCompletion (it is awaitCompletion that triggers the dialog creation)

No, I missed that bit when copying parts of the code - should have copied it all in one go.

See attached movie of the progress bar, it is a solid blue bar
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: New support class for long running tasks
Posted: 31 Oct 18, 07:17   in response to: RobM in response to: RobM
  Click to reply to this thread Reply
The bar looks confusing for sure. I should perhaps put the spinner in its place. Can you show me a video showing how it looks with the Darcula look & feel?
RobM

Posts: 3,808
Registered: 4-Aug-2006
Re: New support class for long running tasks
Posted: 31 Oct 18, 11:03   in response to: davidekholm in response to: davidekholm
  Click to reply to this thread Reply
davidekholm wrote:
The bar looks confusing for sure. I should perhaps put the spinner in its place. Can you show me a video showing how it looks with the Darcula look & feel?
With Darcula I see what I expected, attached.
RobM

Posts: 3,808
Registered: 4-Aug-2006
Re: New support class for long running tasks
Posted: 31 Oct 18, 12:09   in response to: davidekholm in response to: davidekholm
  Click to reply to this thread Reply
davidekholm wrote:
That opens up a world of possibilities (just google "Functional programming")
For future reference and for anyone else reading this thread, here is one source of learning about Funtional programming and for Java and lambda expressions, both are free.
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: New support class for long running tasks
Posted: 31 Oct 18, 21:39   in response to: RobM in response to: RobM
  Click to reply to this thread Reply
RobM wrote:
davidekholm wrote:
The bar looks confusing for sure. I should perhaps put the spinner in its place. Can you show me a video showing how it looks with the Darcula look & feel?
With Darcula I see what I expected, attached.

I think we can live with that, don't you think? Most users use Darcula these days.
davidekholm

Posts: 3,440
Registered: 18-Oct-2002
Re: New support class for long running tasks
Posted: 31 Oct 18, 21:51   in response to: RobM in response to: RobM
  Click to reply to this thread Reply
RobM wrote:
davidekholm wrote:
My number one wish for Java is to get an updated equivalent to BeanShell. I can't imagine that this excellent way of scripting in Java should only be of use for jAlbum skins.
Given I don't know what I'm talking about - the dangers of searching the net - what about Groovy?

I think it's a really interesting candidate. I don't remember why I didn't explore Groovy further last time (Feb 2018). Perhaps it comes back to me if I give it another try. Groovy is definitively a better language than JavaScript, and now Oracle's Nashorn Javascript engine has been deprecated.

Groovy 3.0 is scheduled for release in early 2019. I hope they keep that schedule and that it's not as broken as the 3.0 alpha is now (can't even evaluate new JFrame("bla") right now). The good thing with Groovy 3.0 is that it allows Java syntax for both arrays and Lambda expressions, and Java 10:s new "var" keyword is supported too so the syntax is really close to Java (good if one wants to move to compiled Java code later).

I'm currently testing the last official Groovy version. It's 2.5.3. What bothers me is that, although Groovy in theory could be a great scripting language replacement for BeanShell, they've made a rather weak JSR-223 (aka javax.scripting) implementation. jAlbum interfaces with all supported scripting languages via the JSR-223 API. One thing lacking via Groovy's JSR-223 implementation is the ability to set default imports. For scripting to be convenient, I really want to be able to import jAlbum's main packages as well as javax.swing and others by default. Otherwise each Groovy script would need to start with those imports and what's worse, Groovy doesn't remember imports between script invocations so playing around with the language and jAlbum's classes or Swing UI classes in jAlbum's system console (creating "mockups") becomes tedious as you can't just refer to such classes without importing their respective packages again and again. I've now sent a request to the Groovy people for a resolution to this. Let's see if they have one.
Legend
Forum admins
Helpful Answer
Correct Answer

Point your RSS reader here for a feed of the latest messages in all forums