How to execute after no input happend for some time - java

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);

Related

The effects of firing off a runnable multiple times using a Handler

I have simple runnable like so
private Runnable runnable = new Runnable()
{
#Override
public void run()
{
someVariable = true;
}
};
I use it with a Handler and delay like this
handler.postDelayed(runnable, 60000);
if this functionality gets spammed and the above is called repeatedly it adds runnable multiple times to the message queue.
if this is the case is there away to check if there is one in the message queue first before adding another?
Hi the way I do is to remove the messages and callbacks after my handler runs once. A simple example of my code would be
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
#Override
public void run() {
Log.d("runnable", "handler invoked just once");
handler.removeCallbacksAndMessages(null);
}
};
handler.postDelayed(runnable, 2000);
handler.postDelayed(runnable, 2000); // demo: if this is called multiple times my runnable code wont run

Program should wait after Textfield changed its text

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

Simulate Android button click programmatically [duplicate]

This question already has answers here:
How to simulate a touch event in Android?
(7 answers)
Closed 4 years ago.
I've seen this route,
View.performClick();
but it doesn't show the actual press of the button. I've also tried this method,
btn.setPressed(true);
btn.invalidate();
but, it just shows the button being pressed down. I've narrowed it down to this code, which presses down, and releases, but doesn't click. Am I missing something? How can I do a complete click as if though the user was clicking (monkeyrunner is not an option as of right now)
btn = (Button) findViewById(R.id.btn_box);
Handler handler = new Handler();
Runnable r = new Runnable() {
public void run() {
btn.setPressed(true);
btn.invalidate();
Handler handler1 = new Handler();
Runnable r1 = new Runnable() {
public void run() {
btn.setPressed(false);
btn.invalidate();
}
};
handler1.postDelayed(r1, 1000);
}
};
handler.postDelayed(r, 1000);
Your code is fine. just add btn.performClick(); after the invalidate();
And for better look you can reduce the time of handler1.

Multithreading in JavaFX hangs the UI

I have a simple JavaFX 2 app, with 2 buttons, saying Start and Stop. When the start button is clicked, I want to create a background thread which will do some processing and update the UI (e.g a progress bar) as it goes along. If the stop button is clicked, I want the thread to terminate.
I've tried to do this using the javafx.concurrent.Task class which I gathered from the documentation would work fine for this. But whenever I click Start, the UI freezes/hangs rather than staying normal.
Her's the code from the main Myprogram extends Application class for showing the buttons:
public void start(Stage primaryStage)
{
final Button btn = new Button();
btn.setText("Begin");
//This is the thread, extending javafx.concurrent.Task :
final MyProcessor handler = new MyProcessor();
btn.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent event)
{
handler.run();
}
});
Button stop = new Button();
stop.setText("Stop");
stop.setOnAction(new EventHandler<ActionEvent>()
{
public void handle(ActionEvent event)
{
handler.cancel();
}
}
);
// Code for adding the UI controls to the stage here.
}
Here's the code of MyProcessor class:
import javafx.concurrent.Task;
public class MyProcessor extends Task
{
#Override
protected Integer call()
{
int i = 0;
for (String symbol : feed.getSymbols() )
{
if ( isCancelled() )
{
Logger.log("Stopping!");
return i;
}
i++;
Logger.log("Doing # " + i);
//Processing code here which takes 2-3 seconds per iteration to execute
Logger.log("# " + i + ", DONE! ");
}
return i;
}
}
Pretty simple, but the UI hangs whenever I click the Start button, though the console messages continue to get displayed (Logger.log simply does System.out.println )
What am I doing wrong?
Task implements Runnable, so when you call handler.run(); you actually run the call method in the UI Thread. That will hang the UI.
You should start the task in a background thread, either via an executor or simply by calling new Thread(handler).start();.
This is explained (maybe not very clearly) in the javadoc or in the JavaFX concurrency tutorial.

How to Delay MessageDialogBox in Java?

So in this chunk of code:
//Actions performed when an event occurs.
public void actionPerformed(ActionEvent event)
{
String command = event.getActionCommand();
//If btnConvertDocuments is clicked, the FileConverter method is called and the button is then disabled [so as to prevent duplicates].
if (command.equals("w"))
{
new Thread(new Runnable()
{
public void run()
{
FileConverter fc = new FileConverter();
}
}).start();
btnConvertDocuments.setEnabled(false);
//Validation message ensuring completion of the step.
JOptionPane.showMessageDialog(this, "Step 1 Complete!", "Validation", JOptionPane.INFORMATION_MESSAGE);
}
It seems like the message dialog window pop-ups way too fast, before the FileConverter method isn't even finished being called. I was wondering if the placement of JOptionPane was correct, or if there was a way to delay a message until the method finished processing?
You can use the SwingWorker.
Have a look here, java tutorial.
SwingWorker worker = new SwingWorker<Void, Void>() {
#Override
public Void doInBackground() {
FileConverter fc = new FileConverter();
return null;
}
#Override
public void done() {
JOptionPane.showMessageDialog(this, "Step 1 Complete!", "Validation", JOptionPane.INFORMATION_MESSAGE);
}
};
You should use a Swing Timer with a delay, instead of using your own Thread and Runnable for this.
You can use Swing timers in two ways:
To perform a task once, after a delay.
For example, the tool tip manager uses Swing timers to determine when to show a tool tip and when to hide it.
To perform a task repeatedly.
For example, you might perform animation or update a component that displays progress toward a goal.
An example from the documentation:
int delay = 1000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
//...Perform a task...
}
};
Timer myTimer = new Timer(delay, taskPerformer);
myTimer.setRepeats(false);
myTimer.start();

Categories