Updating calculated values in Android layouts using SeekBar - java

So, I've been working on an app that has a Plan model with a number of different inputs and outputs, and the layout of the app has slider controls for the inputs and labels for the outputs. When an input changes, it updates the model, which then runs a calculation, and then updates the views. I didn't think there was anything wrong with this architecture at first, but even simple calculations seem to run really slowly, blocking the UI thread. Granted, I do have a somewhat complicated way of updating things:
Slider (in a viewgroup subclass) updates its value and sends a message to a delegate (which implements an interface specific to that viewgroup subclass).
Delegate (which holds the model and the control subviews) tells the Plan instance to set a new value, which triggers the plan to recalculate its outputs.
Once the plan finishes its calculations, it sends another message to the delegate, which then tells its output views to update with the new values.
I've modeled this architecture off of an iOS app that I developed which didn't seem to have as big of a problem running the calculations.
Now, I know that Android is significantly different than iOS, so I'm wondering if I'm going about this completely wrong. Is there a way to just tell these views to watch the Plan model for changes and then grab the value it's supposed to display?
Another major issue that I'm seeing here is with the slider input. If I put the model update calculations into a thread, every time the slider changes, a new thread will be created. These threads (as I've seen) will more or less finish in random order, updating the view in such a way as too make very little sense when you should see incremental changes. Is there a good way of threading calculations that are supposed to be changeable with a seekbar?

Have you looked at Observer and Observable?
Maybe your observed model can perform the update using Runnable and then notify the observer.

This is just an idea of the top of my head:
Instead of just starting a new thread for each update from the slider, you could implement some kind of Queue.
You would need a to have a Thread running, that holds the Queue.
public class QueueThread extends Thread {
private boolean running;
private ArrayDeque<Runnable> queue;
private Thread current;
public QueueThread() {
running = true;
queue = new ArrayDeque<Runnable>();
current = new Thread();
}
#Override
public void run() {
while( running ) {
if( !queue.isEmpty() && !current.isAlive() ) { //We only want to start a new thread if there is one or more in the queue AND the old task is not runnning.
current = new Thread( queue.pollFirst() );
current.start();
}
else
try {
Thread.sleep( 200 ); //We need a sleep in order to not hammer the CPU.
}
catch( InterruptedException e ) {
e.printStackTrace();
}
}
}
public void stopThread() {
running = false;
}
public void add( Runnable task ) {
queue.addLast( task ); //Here is where we add a task to the queue. The slider (or whoever posts the updates) must have a reference to this thread object.
}
}
Doing this would allow each update to finish before the next is started. I am not sure how it will do in performance. I haven't tested it or anything. It was just an idea.

Related

java netbeans and jprogress bar

in my program I have to use JProgress Bar to show in real Time ,how many pixels are already encrypted ..so i was looking in internet and i found that i should use Thread , i tried but not working ,here is what I've done :
public class progress_barr extends Thread
{
public void run ()
{
JPB_crypt.setValue(prog); // prog is manipulated in showpixels function
System.err.println("progress here !");
}
}
public class calculate extends Thread
{
public void run()
{
showPixel();
}
}
than i call them later , this is how i use it
JPB_crypt.setValue(0);
appel=1; // to initiate show function
calculate calc = new calculate();
progress_barr pb = new progress_barr();
calc.start();
pb.start();
the problem still the same , my program finish data treatment than it set my jprogress to 100 % ..not in progressing but at once !
i need them to work simultaneously
Your general idea of using a thread is correct, but in order to be able to update the JProgressBar on the go with your calculation progress you need to use a SwingWorker.
The idea behind the SwingWorker is the fact that you can have methods running in the backgournd, by using the doInBackground method, which then publish your results to be used by the UI without locking it.
What you do in your bit of code is to actually have two threads that start at the same time. The first one calculates whatever is that you need to calculate and the second is supposed to update on the fly the progress bar.
This approach will not work, because each time the second thread will have to wait for the first one to end it's job in order to get the results.
You can read more about the SwingWorker here:
https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html

java thread immediately update UI

I have a javaFX application which visualizes compuational geometry algorithms. The execution of an algorithm happens in another thread, lets call it mainComputingThread.
An algorithm can update the UI at any time by adding/removing/modifying shapes.
so the code will look like:
//do some computaions (1)
updateUI();
//do some more calculations (2)
What I want know is in the updateUI method to update the UI immediately and prevent the calling thread from running further (marked as (2)) until the UI update is done.
I thought about boolean guards. So the code could would look like:
updateUI(){
boolean guard = false;
Platform.runLater(new Runnable()
{
run(){
//do the actual update
guard = true;
}
});
while(guard==false);
}
I hope you get an idea of what I mean. I'm really curious if there's a better solution for this problem...
Simple approach: block background thread until update is complete:
You need to update the UI on the FX Application Thread. Typically you do this by passing a plain Runnable to Platform.runLater(...).
If you want to wait for that ui update to complete before proceeding, instead create a FutureTask and pass it to Platform.runLater(...). Then you can call get() on the FutureTask, which will block until the task is complete:
private void updateUI() throws InterruptedException {
// actual work to update UI:
FutureTask<Void> updateUITask = new FutureTask(() -> {
// code to update UI...
}, /* return value from task: */ null);
// submit for execution on FX Application Thread:
Platform.runLater(updateUITask);
// block until work complete:
updateUITask.get();
}
This lets the FutureTask handle all the tricky work of waiting and notifying: it is always better to use a higher-level API for this kind of work when you can.
If you like, you can refactor this into a utility method, similarly to Dainesch's answer:
public class FXUtils {
public static void runAndWait(Runnable run) throws InterruptedException {
FutureTask<Void> task = new FutureTask<>(run, null);
Platform.runLater(task);
task.get();
}
}
Alternative approach: ensure that no more than one update is consumed during any frame rendering, blocking the background thread if an update is pending
Here is a somewhat different approach. Create a BlockingQueue with a capacity of 1 to hold the Runnables that update the UI. From your background thread, submit the Runnables to the blocking queue: since the blocking queue can hold at most one element, this will block if one is already pending.
To actually execute the updates in the queue (and remove them, so more can be added), use an AnimationTimer. This looks like:
private final BlockingQueue<Runnable> updateQueue = new ArrayBlockingQueue<>(1);
background thread code:
// do some computations...
// this will block while there are other updates pending:
updateQueue.put(() -> {
// code to update UI
// note this does not need to be explicitly executed on the FX application
// thread (no Platform.runLater()). The animation timer will take care of that
});
// do some more computations
Create the timer to consume the updates:
AnimationTimer updateTimer = new AnimationTimer() {
#Override
public void handle(long timestamp) {
Runnable update = updateQueue.poll();
if (update != null) {
// note we are already on the FX Application Thread:
update.run();
}
}
};
updateTimer.start();
This basically ensures that no more than one update is ever scheduled at any time, with the background thread blocking until any pending updates are consumed. The animation timer checks (without blocking) for pending updates on each frame rendering, ensuring that every update is executed. The nice thing about this approach is that you can increase the size of the blocking queue, effectively keeping a buffer of pending updates, while still ensuring no more than one update is consumed during any single frame rendering. This might be useful if there are occasional computations that take longer than others; it gives these computations a chance to be calculated while others are waiting to be executed.
Hard question to answer without having the reason why you want to stop processing before the UI update is done. (Note: the runLater method executes the UI updates in the order received) Is it to prevent spamming to many Runnables to the JavaFX thread? Other reasons?
Your basic idea however works with the use of a CountDownLatch so that the processing thread waits to acquire a permit. If you choose that approach use something like this:
public class MyFXUtils {
public static runAndWait(final Runnable run) {
final CountDownLatch doneLatch = new CountDownLatch(1);
Platform.runLater(new Runnable() {
public void run() {
try {
run.run();
} finally {
doneLatch.countDown();
}
}
});
doneLatch.await();
}
}
EDIT: replaced Semaphore by CountDownLatch
EDIT:
So, the quickest way I always do it in prototypes is as following, transform:
//do some computaions (1)
updateUI();
//do some more calculations (2)
into
ExecutorService executor = Executors.newFixedThreadPool(1);
class JobStep implements Runnable {
public void run() {
doSomeComputations();
Platform.runLater(() -> {
updateUI();
executor.submit(new JobStep());
});
}
executor.submit(new JobStep());
OLD PART
Not an answer, but a suggestion how to attack the problem.
From my experience, the complete solution would be much more elaborate. I would separate the JavaFX shape instances from the shapes, which your algorithm does process. I would do it by means of using different class types and synchronize between the two.
The graphical algorithms have the tendency to be a lot quicker than the ones that are visualizing it. If the algorithm runs on small data set, then the rendering most often tend to slow down it significantly. It can easily be seen by running the same algorithm with and without visualization.
If the data set is bigger than the most trivial ones, then drawing of a single frame can easily take more than one second. Interactive visualizations are expected to respond in "real time", preferably many times per second.
The data visualization facilities have many means to tackle the problem. The best candidates always include:
Simplifying visualization. Drawing simpler shapes instead of complex, like removing the rounding from boxes. The LOD (level of detail) also applies to this point: during interactive scroll the visualized elements might be replaced by bounding box counterparts.
Selective hiding. Drawing only a part of the whole data set.
Parallelizing and hardware acceleration. The GPU's natively provide many means to handle complex visualizations. Typically the low level programming APIs (OpenGL, shader programs) allow much better throughput than every high level wrapping API, including JavaFX
Most often, the end solutions incorporate not only above points, but also others, including domain specific optimizations.
The visualization facilities always come with a lot of restrictions, like the most common one: have to be updated in the dedicated thread (thread confinement approach). They also come with visualization specific data structures.
From the data processing algorithm stage, one of the most common requirements is that it cannot be blocked or delayed by visualization. The algorithms are also written in a style, which doesn't translate to well for the means of visualization: imperative loops over data structures instead of updating observable drawable objects. There is a good reason to it though: the algorithms are expected to be optimized for performance or memory consumption.
One architectural approach to the problem might be as following:
The data processing stage produces snapshots at predefined points. The adding, modifying and remove operations are all published as this packet. It can be a just a copy of data structure that is being processed or it can be in the form of the coalesced events.
The data processing and data visualization run on different threads. They communicate only by means of publishing snapshots, never by blocking each other directly.
The snapshots shouldn't be restricted to particular frame rate. There should be means to batch updates before drawing or drawing same batch multiple times if the data processing stage stalls.
I strongly recommend reactive approach to the problem. The RxJava provides nice example for the "suggestion box" feature. It's very good at correctly handling requirements like "Every key update do a long running process on different thread and discard the last one, if any was running. Or maybe, don't do it on every key update, but wait 50ms for the user to make up his mind before he ends typing".

JavaFx Updating UI based on notification from Java thread

I am new to multithreading, Java and JavaFx. I am building an application with JavaFX UI which updates a graph continously based on live data. Here is the current design,
1. When a JavaFx button is pressed, I invoke a thread which sets up the framework to send requests and get responses
startButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
stopButton.setDisable(false);
if(!startButton.isDisable()){
runSequence = new Thread(new Runnable(){
#Override
public void run() {
SynchThreads sharedObject = new SynchThreads();
new Bridge(sharedObject);
startSequence = new Sequence(sharedObject);
startSequence.performCalls();
}
});
runSequence.start();
}
startButton.setDisable(true);
}
});
2. runSequence thread which is invoked as above invokes another thread "callbackThread" that constantly receives data. This data which is received is passed to runSequence thread for further processing
BusinessLogic businessLogic = new BusinessLogic();
executor.submit(pduApiDllCallBackThread);//This collects the data in background
//Here we are back on runSequence thread that works on the collected data.
while(true){
response = sharedObject.take();
businessLogic.primeData(response);
}
3. The BusinessLogic class after working on this data notifies the user interface with an event ID and data that should be shown on the graph.
UI.notifyListeners(0, graphCoords);//here event ID is 0 and graphCoords is a HashMap
4. In the user interface everytime I get the notification I update the LineChart by using Platform.runLater. This notification occurs every 4 millisecs. So, I end up doing a lot of Platform.runLater calls
public void notifyListeners(int eventType, Map<Integer, Float> graphCoords) {
Platform.runLater(new Runnable(){
#Override
public void run() {
//Old series is cleared. Showing dummy data being updated
series.getData().clear();
series.getData().add(new XYChart.Data("1", Math.random()+1));
series.getData().add(new XYChart.Data("3", Math.random()+5));
series.getData().add(new XYChart.Data("4", Math.random()-25));
series.getData().add(new XYChart.Data("2", Math.random()-10));
series.getData().add(new XYChart.Data("-1", xxx));
}
});
}
Please provide your expert tips if this is ok to do this or if there is a better way to handle this in UI.I do not have more control over the layer below UI which notifies the UI. As the notification occurs every 4ms I wanted to know if there is a better approach
Any help is appreciated. Please help. Thanks !
You might swamp the JavaFX event queue by executing Platform.runLater so often, so you might want to batch the responses up (say in groups of ten), then make a single runlater call for each batch.
There is a specific codereview site on stackoverflow.
Make sure you have animation turned off on the chart so it doesn't try to do too much with each update.
Your solution does seem a bit complicated, but perhaps it's warranted for your situation, I don't know.
I don't know how you are handling your concurrency, but take a look at java.util.concurrent and the concurrency tutorial if you haven't already. Also checkout Concurrency in JavaFX if you have not already. Sometimes the higher level java.util.concurrent framework is more expressive, less error prone, easier to work with and easier to reason about than the lower level object monitor wait/notify methods.
You may want to mark some of the threads you are using as daemon threads. You may also want to add some logic to handle interruption of threads or cancellation of processes, similar to the examples in the JavaFX Task documentation.
If you are new to Java, multithreading and JavaFX, starting off with a multithreaded, networked JavaFX app is jumping off the deep end.
Often, concurrent work is offloaded from the JavaFX application thread to worker threads using the Task/Service framework.

I've a problem when I use the Sleep?

why in my code, the TextView does not take except the last count.
the result just is: counter= 4
int i =0;
while (i< 5) {
try {
Thread.sleep((i*1000));
mText.setText("counter"+ i);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// mText does not show
mText.setText("counter= "+ i);
i = i +1;
}
You are blocking the UI thread when your app sleeps, so the screen is not redrawn, hence you don't see the text changes until your loop ends.
The UI thread
When an application is launched, the system creates a thread called
"main" for the application. The main thread, also called the UI
thread, is very important because it is in charge of dispatching the
events to the appropriate widgets, including drawing events. It is
also the thread where your application interacts with running
components of the Android UI toolkit.
For instance, if you touch the a button on screen, the UI thread
dispatches the touch event to the widget, which in turn sets its
pressed state and posts an invalidate request to the event queue. The
UI thread dequeues the request and notifies the widget to redraw
itself.
This single-thread model can yield poor performance unless your
application is implemented properly. Specifically, if everything is
happening in a single thread, performing long operations such as
network access or database queries on the UI thread will block the
whole user interface. No event can be dispatched, including drawing
events, while the long operation is underway. From the user's
perspective, the application appears hung. Even worse, if the UI
thread is blocked for more than a few seconds (about 5 seconds
currently) the user is presented with the infamous "application not
responding" (ANR) dialog.
If you want to see how bad this can look, write a simple application
with a button that invokes Thread.sleep(2000) in its OnClickListener.
The button will remain in its pressed state for about 2 seconds before
going back to its normal state. When this happens, it is very easy for
the user to perceive the application as slow.
To summarize, it's vital to the responsiveness of your application's
UI to keep the UI thread unblocked. If you have long operations to
perform, you should make sure to do them in extra threads (background
or worker threads).
More info:
http://developer.android.com/resources/articles/painless-threading.html
That is the problem. And AsyncTask is (one) solution:
AsyncTask
AsyncTask enables proper and easy use of the UI thread. This class
allows to perform background operations and publish results on the UI
thread without having to manipulate threads and/or handlers.
An asynchronous task is defined by a computation that runs on a
background thread and whose result is published on the UI thread.
http://developer.android.com/reference/android/os/AsyncTask.html
First, it would be a good idea to change the text before sleeping.
Second, if you do this in a separate thread, you have, nevertheless, to manipulate a widget in the ui thread. Try this :
instead of
mText.setText("counter"+ i);
try
runOnUIThread( new Runnable() {
public void run() {
mText.setText("counter"+ i);
}
});
Regards,
Stéphane
"while (i <= 5)" will make it go on till five.
Another solution is to make "i" 1 to start with, instead of 0.
Does this help?
Use a for loop (inside a non-UI thread):
for (int i = 0; i < 5; i++}{
try {
Thread.sleep((i*1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
runOnUIThread(new Runnable() {
public void run() {
mText.setText("counter"+ i);
}
});
}
Many answers here gave you all the information you need to achieve what you want but it may be difficult to understand.
I will propose you below a new way to achieve it, maybe easier. But I want to underline that you should understand what people wrote, my previuos post and the one from #LAS_VEGAS at least.
Here is something easy : use a handler.
add a data member like
Handler handler = new Handler();
then on click :
for (int i = 0; i < 5; i++}{
handler.postDelayed( new Runnable() {
public void run() {
mText.setText("counter"+ i);
}
}, i * 1000 );
}
I don't have access to my very own computer right now and fear this may not compile due to a non final variable used inside a annonymous inner class. So you could also try to build a named inner class like this in your main java class :
public class ButtonTimerThread implements Runnable
{
privqte int i =0;
public ButtonTimerThread( int i)
{
this.i = i;
}//cons
public void run()
{
mText.setText("counter"+ i);
}//met
}//class
qnd then you click listener method would look like :
for (int i = 0; i < 5; i++}{
handler.postDelayed( new ButtonTimerThread( i ), i * 1000 );
}
As your handler will be created by the UI thread, it will be able to update UI. The handler offers the advantage to have a delay mechanism that doesn't block the UI thread that is reacting to your click action.
I hope this helps,
Stéphane
Generally, good solutions to problems with sleep() involve stopping using sleep(). Blocking the UI thread is always a very bad idea. It makes you application's UI non-responsive.
In your case you want an event to run every second. The correct way to implement that is with a timer.

Multi threaded game - updating, rendering, and how to split them

So, I'm working on a game engine, and I've made pretty good progress. However, my engine is single-threaded, and the advantages of splitting updating and rendering into separate threads sounds like a very good idea.
How should I do this? Single threaded game engines are (conceptually) very easy to make, you have a loop where you update -> render -> sleep -> repeat. However, I can't think of a good way to break updating and rendering apart, especially if I change their update rates (say I go through the update loop 25x a second, and have 60fps for rendering) - what if I begin updating halfway through a render loop, or vice versa?
Place your update logic in some kind of Updater worker class (implementing Runnable), and put renderer into separate worker class. When you need to update data, let Updater put that update into queue shared by both Updater and Producer. Most convenient would be to use queue which already have built-in multi-threaded support, like subclass of BlockingQueue. For example code, see javadoc for BlockingQueue.
Using queue is natural if you need to render all changes, even obsolete ones. If you wish to render only the latest change, use ConcurrentHashMap instead of queue.
Don't forget to make your updates immutable objects, so there's no chance update can change while you render it.
As Nirmal pointed out, you could use some kind of thread pool to limit number of threads and to simplify starting/stopping of threads. Refer to Executor interface and Executors utility class in JDK to see available options here.
I would suggest going pipeline with this architecture, meaning that the render stage will render all the elements updated on the previous frame, it would go like this:
Update 0
Update 1 Render 0
Update 2 Render 1
Update 3 Render 2
....
it would mean that your game will use more memory and all the objects will have to have per frame states / data
if you introduce more layers in this pipeline your game will suffer from input lag (meaning the user will see his action on the screen later then normal), so I suggest to using just this 2 stage pipeline
create pojo for every category, one runnable object contains data like fps rate, UI screen class n all requited information, you can make common information singleton, so at every time rendering start thread for updating, i recommend threadpool to keep memory consumption limited
Also note that your draw thread should never run faster then your update thread. Since if your update thread is not done with the current step yet, you will draw the same thing as before. While doing this you might miss the finishing of the update step, which in the end causes lower than optimal framerate.
(Remember drawing the exact same picture as before doesn't benefit anyone).
I've made my program using three threads (though more could be used).
Update logic (Does the data collecting and pre-processing)
Helper thread (Calculates time consuming cache pre calculations etc. at infinite sleep 1ms loop ... So this thread does not care where Update logic is going, or how fast. It just checks where it is going and calculates iF it needs to cache new items)
Render thread (Does ONLY rendering, everything it needs to render is pre-processed so it does only draw functions and calculates screen positions)
Doing this is super easy if you just have "thread safe" items you are drawing. But in game, I personally think that it is not bad thing if you render player 1 one tick ahead than player 2... Because you still want to draw as fast you can on games. Game logic thread makes sure there is no logical exceptions... So usually I think it does not matter what you draw and when, you just do it as fast as you can without thinking any "synchronizations".
I presonally prefer public static volatile item to share data between threads. And AtomicIntegerArray is a useful class for that too.
I would say add a field that specifies the thread needed to run and render, and number the threads, if the thread number == the thread required, then it is allowed to run and render, and increment the required thread field, until it hits max, then loop back to 0. Alternatively, you could, use one thread for tick and another for render, this might be easier. Here is an example code:
public Game() {
this.tickThread=new Thread(this::tickLoop());
this.renderThread=new Thread(this::renderLoop());
}
public void tickLoop() {
//code for timing...
while(running) {
//more code for timing...
tick();
}
}
public void renderLoop() {
//code for timing or syncing frames...
while(running) {
//more code for timing...
render();
}
}
Alternatively, you could say:
|MyRunnable.java|
public interface MyRunnable
{
public abstract void run(boolean toRender);
}
|MyThread.java|
public class MyThread extends Thread
{
private boolean isRender;
private MyRunnable runnable
public MyThread(boolean isRender,MyRunnable runnable)
{
this.isRender=isRender;
this.runnable=runnable;
}
public void run()
{
this.runnable.run(this.isRender);
}
}
|Game.java|
public class Game extends /*JPanel/Canvas/JFrame/Some other component*/
{
private MyThread tickThread;
private MyThread renderThread;
private boolean running;
public Game()
{
super();
tickThread=new MyThread(this::run);
renderThread=new MyThread(this::run);
//other constructor code
}
public void tick()
{
//tick code here
}
public void render()
{
//render code here
}
public void run(boolean isRender)
{
//timing variables
while(running)
{
//timing code
if(isRender)
{
this.render();
}
else
{
this.tick();
}
}
}
}

Categories