mabe02 / lanterna

Java library for creating text-based GUIs
GNU Lesser General Public License v3.0
2.25k stars 242 forks source link

Loading Animation (Proposal) #357

Open EweLoHD opened 6 years ago

EweLoHD commented 6 years ago

I looked in the Docs and I found nothing like a loading Animation. I mean something like the Progress Bar but which is never full:

It would be nice when you could add something like this (or show me what I didn't saw in the Docs xD)

mabe02 commented 6 years ago

Sure, this is probably what you want: http://mabe02.github.io/lanterna/apidocs/3.0/com/googlecode/lanterna/gui2/ProgressBar.html

avl42 commented 6 years ago

I didn't read it that way...

I think, EweLoHD wants a kind of "BusyIndicator" where both start and end of the "bar" will move like a marquee. It is no longer strictly a ProgressBar that way, but at some point, it could quickly change into a proper progressbar, once the displayed progress becomes measurable for the application.

(I think of a download progressbar, where at first nothing is known about download size or bandwidth, so it just indicates "I'm still alive" but once the connection is established and it knows the total size it'll display the fraction transferred so far.)

The non-trivial part of it would be the animation. Lanterna would need something like Timers for that. But now that I mention it, Timers would be a cool addition, anyway. Timers could be implemented as special "KeyStrokes" that would be set up for a particular timespan, and could also be set up as single-shot or repeating.

avl42 commented 6 years ago

One period of sleep later I'm not so convinced about the KeyStroke thing... The Timer could just simply "run()" a provided Runnable.

The truly relevant part would be that a timer would need to run in the GUI thread, invoked from within TextGUIThread.processEventsAndUpdate().

Within that method it would also consult a priority queue of Timers, and if the front-most Timer has elapsed it will be eventually re-scheduled(if so configured), then its run() invoked. There is already a similar mechanism for invokeLater, but this would be a separate queue, as it would only be processed partially: only while there's an elapsed timer at the front.

It's possible to use Java timers and invokeLater, but if the program is busy for a while, such invokeLater's might stack up. I'd rather have synchronous timers.

mabe02 commented 6 years ago

Oh, it's like the "indeterminate" mode of the JProgressBar? I can see how that would make sense....

For timers, I already did something for the animated label but honestly I wasn't so happy about it. I tried to make a timer that would only keep a thread around for as long as the animation is running and then get rid of it. Didn't want to create any extra background threads at all if avoidable. We could try to implement something as part of the TextGUIThread, either by wrapping the java.util.Timer or by doing something custom. Ideally I'd like to not have any additional threads apart for the designated UI thread, but maybe a good compromise would be to start the timer thread only when a timer task is added?