I am a Java newbie and an Android newbie too. I am working on a game and trying to understand the exact nature of events in Java and Android. I have a few questions to help understand the correct way to do event handling in my app.
Its a network game and so I need to check if the user made a move or not to update the view. Also I need to prompt the user to make a move if he takes too long. For this I have two threads -
Timer thread expires every 10 seconds and calls updateview if needed or prompts user to make a move.
Event thread gets created when user clicks on the screen to make a move or clicks on menu etc.
Is this the correct approach? These two can be fired at any time.
Here are the issues I see with this -
What happens when one thread gets run when the other one is active.
Which thread has precedence if both are started at the same time.
Do events in the timer thread get queued up?
If so can I pick which one in the queue to use?
Can I cancel events in the queue? For e.g. if I have 2 updateview events lined up in the queue I only have to call it once.
Thanks for any inputs.
P
I would suggest reading up on Android AsyncTask.
Consider that you can implement a timer WiTHOUT using a thread. Use a single Handler switching on what and send a postMessageDelayed(what 0,milliseconds) to the handler say every one second. You could set a counter variable to zero and check the flag every one second in the what 0 handler, incrementing the counter by one. If the value is >= ten, post a message and reset the variable to zero. If the user selects an action, reset the instance variable to zero.
A time consuming action can be run in a separate thread that messages the handler, perhaps using what 1, on completion. Or you could run a time consuming action in a separate asyncTask.
JAL
Related
I am making a javafx application that simulates a robot vacuum.
I want it to be automated so it would vacuum the environment by itself.
I need to insert a delay so a human can see the steps the vacuum is taking as it traverses the environment.
So far all the delay methods I have tested crash my program if they are inside a while loop.
If I put it outside the while and just click a button for the next step, everything works fine.
It also works fine if I set the delay to really short time, like 1 ms.
Any ideas of why this is happening?
Any application that executes a set of instructions for a while (is busy) and cannot respond to user input or system events is "seen" by Windows as "not responding" and when you try to interact with a "not responding" program, Windows will tell you it crashed.
The problem, you see, is that you try to delay interface updates with a while loop, and that makes your program execute something for a while and while is busy executing your loop it cannot respond to system or user events.
If you want to make delayed updates, use multithreading. Your while loop is blocking the main thread which is also responsible for rendering and taking any input, so you cannot block this thread. Create another thread and share state (eg. use observer pattern). And then you can execute TimeUnit's sleep() in this helper thread and it won't make your app "crash".
int time = 0;
time++; // set by 1second
int countdata = 0; // countdata queried by table shows the numbers of table values
rs = stmt.executeQuery("SELECT ID,test From Table");
StringBuilder strBuilder = new StringBuilder();
while (rs.next()) {
strBuilder.append(rs.getString(0)).append(" ").append(rs.getString(1));
strBuilder.append("\n");
if(time <= countdata){
// this is my idea but i dont know how to fetch the data each row
}
jtextarea.setText(strBuilder.toString());
}
the output is like this:
// time 1 seconds
test1
// time 2 seconds
test2
// time 3 reconds
test3
//until it reach the last data of table
please help
i want to fetch data by every 1 second until it reach the last value. the time is fix by 1 second delay. every 1 second shows the row of data.
You have two basic choices (there are others, but lets keep it simple...)
Basically, you want to perform the query in some kind of background thread but ensure that the updates to the UI are carried out within the context of the Event Dispatching Thread...
This ensures that while the query is taking place, the UI remains responsive to the user and to won't make it look like your application has crashed...
You Could...
Use a Swing Timer to schedule a call back every n milliseconds. The benefit of this is that it the callback is triggered within the context of the Event Dispatching Thread.
The drawback is that the callback is triggered within the context of the Event Dispatching Thread.
The main problem I see is you don't want to be querying the database from the context of the EDT as this will prevent it from performing updates to the UI and remaining responsive to the user while the processing is occurring.
Now you could spawn another Thread at this stage, but the problem is, the time it takes to complete the query may be more than the time allocated between updates, meaning that it would be possible for last query to still be running when the next one is triggered. You also run into issues with having to synchronise updates to the UI manually, while not especially difficult, why would you want to make life more difficult ;)
Take a look at How to Use Swing Timers and Concurrency in Swing for more details
You Could...
Use a SwingWorker. This will allow you to perform the query in a background thread while providing you with functionality to send updates back to the Event Dispatching Thread so the UI can be updated properly.
The drawback with this is that the SwingWorker doesn't have timer concept of it's own, but, you could simply use Thread.sleep.
Now, depending on whether you want regular updates; ie they MUST occur every second, exactly, or delayed updates; ie they must occur every second AFTER the last update will depend on how you use this, but what this means is you gain control.
Basically what this means is, you can ensure that only one query is been executed at a time and control the amount of time before the next one.
Take a look at Worker Threads and SwingWorker for more details
I'd like to ask you about the best solution/idea how to solve a following situation.
I'm developing an Android app which on one of screens has a set of buttons. After clicking on any of them a kind of config is posted to the server over http.
To prevent multiple clicks one by one which could result in concurrency problems I decided that after each click on a particular button there'll be a waiting interval of 30 seconds before a config is sent to the server. If another click on the same button happens before this 30 seconds are exceeded, then the execution of method is delayed for another 30 seconds - as long as no new click is performed, then the config will be sent.
I need an idea of an algorithm which would implement the mechanism above. What I know is that I don't want to start a separate thread for each click (too heavy for my app). A potential idea is to make a queue of events and send them in a loop but idea of a running endless loop in a thread (or Handler) also isn't my favourite.
Maybe there's a kind of mechanism in Android or J2SE in general, that allows to schedule an execution of method to a given time in the future but still be able to postopone execution for some additional time before 30sec rolled out.
thanks in advance!
I have been trying to find a solution to this question for a while. What is the best practice for writing a swing event buffer? The idea is when triggering an action from a mouse gesture, such as 'mouseMoved', as the events may be fired many times, I only want to trigger the last call - for example,
if the mouse was clicked five times, while the first click listener is being executed, and four are queued, the next call will be the fifth one - all previous ones will be skipped.
It seems that I should be using the Executor class, as it can remove unsubmitted tasks, but I am still not quite sure. All help is appreciated!
user1291492 is right, this shouldn't happen at all. You should never run any code that could take longer than a couple of milliseconds to complete in an event handler. The SwingWorker documentation contains examples and explanations on how to do it. The most important quotes is
Time-consuming tasks should not be run on the Event Dispatch Thread. Otherwise the application becomes unresponsive.
To address the original question, there are two patterns I usually employ:
Use flags to mark actions that should be executed at some point in the future. When there's no other work for some time I check all the flags, reset them and perform the appropriate actions.
When scheduling work for a worker thread, hold a reference to it. Every time before scheduling new work, cancel the previously scheduled work. Most often used with CancellationTokens in C#/Async.
In my Java program, I have a text component that can fire events in rapid succession. Since I'm doing a lot of background processing whenever the text is modified, this can noticeably decrease the responsiveness of the text component. That's why I'd like to introduce a delay: When the text component starts firing, the attached listener should wait for a certain amount of time (e.g. 1 second) until the text component has "calmed down", and then start its own processing.
I know that it's relatively easy to roll my own simple delay mechanism that does what I want, but I'm wondering if the java.util.concurrent package (or some other system package) has a ready-made solution for this. I've been looking into
Executors.newScheduledThreadPool(int)
but this doesn't seem to be what I'm looking for, since this will fire all incoming events - I only want exactly one event to make it through to the listener after the delay.
Thanks in advance.
You're very close to the solution.
What you want is to schedule a firing of the listener to happen one second in the future, but to cancel that when the next event arrives (if it hasn't already happened) and reschedule. Using an executor is reasonable, but the key is that you need to keep around the Future object that scheduling returns, as it is that which you cancel.