My Testprogram should change a TextViews text and after it is done, it should wait on second before the next text change. However my program runs the text changes instant behind each other:
t.setText("Test!");
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
t.setText("Test - after 1 second!");
}
},1000);
The first text is not even there close to a second.
Hard to say why that wouldn't work from that limited amount of code but you can just add the post delayed to your View. You don't need a handler.
t.setText("Test!");
t.postDelayed(new Runnable() {
#Override
public void run() {
t.setText("Test - after 1 second!");
}
}, 1000);
All Views in Android have a built in handler class.
You are missing the following:
handler.postDelayed(this, 1000);
inside the run method. Here this will refer to the handler object
Related
I have a problem with a long running task.
After my dialog is shown I want to scan a ftp directory. This task takes some time so I need to run this task no in the UI thread.
My idea was
#Override
protected void postDialogOpen() {
// if invoked via menu button
if (!scanFtp) {
final Display display = Display.getDefault();
new Thread(new Runnable() {
#Override
public void run() {
//initProgressWaitViewer();
scanFtpServer();
//closeProgressWaitViewer();
display.syncExec(new Runnable() {
#Override
public void run() {
updateTree();
}
});
}
}).run();
}
}
But during the execution of scanFtpServer() my dialog is not movable and if I click on it it becomes "unresponsible".
Is there something I am doing wrong?
When calling method run() in class Thread, you are executing the method on the caller thread, just like calling any other method. If you want to spawn a new thread and execute method run() in that thread, you need to call method start() instead, that will do all the work of setting up the thread and running it.
So replace
}).run();
with
}).start();
Try to do .start() instead of .run() .
I'm developing an Eclipse plugin that will contribute to the GUI with a view.
The view is updated with informations from a versioning system when the user selects a folder or a file in the workspace.
In order to avoid collecting data everytime the user goes through the project subfolders and files, I need to wait for 3 seconds in order to be sure that the file or folder is the one of interest.
I'm currently doing this using a Swing Timer.
This is ok for small amount of data, but for large amount of data the GUI blocks, waiting for the timer to execute the update function.
I know for this kind of task I can use SwingWorker but I can't figure out how to delay the task and to restart the delay when needed.
Can anyone give me a solution on how to correctly solve this problem ?
Here is my current code:
public void resetTimerIfNeeded()
{
if(timer.isRunning())
timer.restart();
else
timer.start();
}
public void timer()
{
selectionTimer = new Timer(3000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
Display.getDefault().syncExec(new Runnable(){
#Override
public void run()
{
updateView();
selectionTimer.stop();
}
});
}
});
}
Since Eclipse uses SWT rather than Swing it is best to avoid using Swing code.
You can run code in the UI thread after a delay using UIJob, something like:
UIJob job = new UIJob("Job title") {
#Override
public IStatus runInUIThread(IProgressMonitor monitor) {
updateView();
return Status.OK_STATUS;
}
};
job.schedule(3000);
Alternatively you can use Display.timerExec:
Display.getDefault().timerExec(3000, new Runnable(){
#Override
public void run()
{
updateView();
}
});
Schedule it as a Job instead: https://eclipse.org/articles/Article-Concurrency/jobs-api.html . Use a UIJob if the entirety of what it's doing is interacting with the UI. The cancel/schedule and sleep/wakeUp methods will be of interest , see http://help.eclipse.org/luna/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/core/runtime/jobs/Job.html for the JavaDoc.
I want to run my program where the value of a label changes after the Timer goes off. But whenever the Timer runs I will keep getting the Invalid Thread access error and my label does not get updated.
protected void createContents() {
<--GUI codes -->
//Timer set to go every 10 seconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
System.out.println("Timer");
lblState.setText("On");
}
};
new Timer(delay, taskPerformer).start();
}
This link from the SWT FAQ explains the error and how to solve it: any code that modifies GUI components (in your case, setting the text of the label) needs to run on the display thread, otherwise this error will occur.
To run on the display thread, wrap the code inside a Runnable and call Display.getDefault().syncExec( with the provided Runnable:
Display.getDefault().syncExec(new Runnable() {
public void run() {
// code that affects the GUI
}
});
All access to UI objects must be done in the user interface thread. You can do this using Display.asyncExec (or Display.syncExec).
Change your line:
lblState.setText("On");
to
Display.getDefault().asyncExec(() -> lblState.setText("On"));
for Java 8. For Java 7 or earlier use:
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run()
{
lblState.setText("On");
}
});
I need tu update my TextView every second. I wrote it with Timer and TimeTask but everyone says its deprecated method.
Can someone show me how to make simple timer which updates TextView every 1 second with possibility stop it from UI?
You can use a handler or a count down timer
Handler m_handler;
Runnable m_handlerTask ;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something. update text view.
m_handler.postDelayed(m_handlerTask, 1000);
}
};
m_handlerTask.run();
To stop
m_handler.removeCallbacks(m_handlerTask);
Check this link for countdowntimer ,handler, timer
Android Thread for a timer
No need to create a separate Handler for this (as in the currently accepted answer). In stead, just postDelayed() the Runnable directly to the TextView's internal message queue:
Runnable runnable = new Runnable () {
#Override public void run() {
// do some work, then repost:
textview.postDelayed(runnable, 1000);
}
};
// post with an initial 1000 ms delay
textview.postDelayed(runnable, 1000);
// or post without an initial delay
textview.post(runnable);
// or even run the runnable right away the first time
runnable.run();
Alternatively, if all you're trying to accomplish is to 'redraw' the TextView, use invalidate() (or postInvalidate() from a non-UI thread). There are also overloads that allow you to restrict the invalidation to a specific rectangle, which you can potentially exploit for a more efficient implementation.
You could use a simple handler to do what you need to do. Anyway, with the scheduler way you could do:
private ScheduledExecutorService scheduler;
...
if(scheduler != null)
{
scheduler.shutdown();
scheduler = null;
}
scheduler = Executors.newSingleThreadScheduledExecutor();
scheduler.scheduleAtFixedRate(new Runnable()
{
public void run()
{
// do your stuff...
}
}, Consts.KEEP_ALIVE_TIMEOUT, Consts.KEEP_ALIVE_TIMEOUT, TimeUnit.MINUTES);
I am trying to achieve the following behavior:
You press a button which toggles through multiple elements (in swing). The point is, that a message or whatever should only appear if no toggle happened in the last second. That means you press button1, wait one second, then comes the message you pressed button1; and if you press button1, then (under one second) press button2, the message should say button2 was pressed.
I found some timer stuff like this (as i know now, this is a android example. perhaps there is something similar to this for swing??):
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Do something after 1000ms
}
}, 1000);
How could I stop the task? I don't need any code, just a hint.
For code
final Handler handler = new Handler();
Runnable runIt = new Runnable() {
#Override
public void run() {
//Do something after 1000ms
}
}
handler.postDelayed(runIt, 1000);
you can delete message from queue by
handler.removeCallbacks(runIt);