I have an application which runs a timer to check for idle time and once there is no activity for 10 seconds the application will close. I have nearly 100 screens and i want to track the inactivity seconds on all the screens. Its hard for me to write the handling events in all buttons, textboxes, labelboses one by one. What i have to do is add 10 seconds on every action of the user on the application. Even if it is mousemove add 10 seconds so tat the application wont close for another 10 seconds. Is there any way to handle this effectively ?
I would suggest the following handler:
final Timer tm = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("10 SECONDS AND NOTHING HAPPENED");
}
});
tm.start();
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent event) {
tm.restart();
}
}, -1);
You could look into Toolkit.addAWTEventListener this allows you to add a MouseMotionListener to react to mouse movements throughout your app and act accordingly.
Related
I am trying to setup a program that enables the user to display a transition when clicking the next and previous button. When pressing next, the swing timer should trigger and start the animation. When transitioning, there should be a flag that states it is in the transition period. The Swing timer should fire once every tenth of a second and essentially last 1 second.
public class guiCreation {
static Timer timer;
static boolean flag = false;
private static void guiInterface() {
next.addActionListener(new ActionListener(){
timer = new Timer(1000, this);
public void actionPerformed(ActionEvent e){
nextGest();
}
});
//should go to the next tab
previous.addActionListener(new ActionListener(){
//if the list gets to the beginning, disable button
public void actionPerformed(ActionEvent e){
prevGest();
}
});
}
public static void nextGest() {
timer.start();
previous.setEnabled(true);
next.setEnabled(true);
//if the list gets to the end, disable button
if (cardLayout.isNextCardAvailable()) {
status.setText(" Next button has been clicked");
//System.out.println("This is the" + size);
cardLayout.next(cardPanel);
next.setEnabled(cardLayout.isNextCardAvailable());
}
}
public static void prevGest() {
if (cardLayout.isPreviousCardAvailable()) {
timer.start();
next.setEnabled(true);
previous.setEnabled(true);
status.setText(" Previous button has been clicked");
cardLayout.previous(cardPanel);
previous.setEnabled(cardLayout.isPreviousCardAvailable());
}
}
}
This: "The Swing timer should fire once every tenth of a second ..." -- does not agree with this: timer = new Timer(1000, this); Your Timer is firing once every second, not every 10th of a second.
Instead, you should:
Create a new Timer(100, ...), one that fires every 10th of a second
Store in an instance field the start time in msecs when the Timer begins (likely do this in your button's ActionListener)
Within the Timer's ActionListener get the current mSecs and use this to check the elapsed time
Stop the Timer via ((Timer) e.getSource()).stop(); once 1 full second has elapsed
No need for a flag, since all you need to do is to check if the Timer isn't null and if it .isRunning(). e.g., if (timer != null && timer.isRunning()) { -- then the animation is proceeding.
Unrelated suggestion:
Get out of the static world and into the instance world. You're programming in Java, a language that is built to use OOPs from the ground up, and you don't want to fight against the OOPs paradigm.
My grid is not refreshing automatically after adding a row. I've tried several solutions from other questions but they didn't work. E.g. grid.clearSortOrder(); and grid.markAsDirty();. My goal is to add rows after time periods. Therefore I'm using a Timer and the rows are added but the grid does not refresh until I click in the table.
Easy code example:
Grid grid = new Grid();
grid.addColumn("Name");
grid.addColumn("Age");
Timer timer = new Timer();
timer.schedule(new TimerTask(){
public void run(){
grid.addRow("Exmaple","99");
}
}, 1000, 1000);
You will Need Server push for this. See Vaadin-Doc-Serverpush.
You want to change the UI from another Thread (Timer.schedule() will execute in another thread).
Vaadin callbacks are triggered by user interactions like mouse press on a button, selection of an option and so on. When you need the user interface to reflect a change that was not caused by the mouse/keyboard, you need to enable server push:
#Push
public class App extends UI {
#Override
public void init(VaadinRequest request) {
timer.schedule(new TimerTask() {
public void run() {
access(() -> grid.addRow("Example", "99"));
}
}, 1000, 1000);
}
}
Note the usage of UI.access(Runnable) to lock the UI when it is accessed from a non-request thread.
I am trying to do the following: click a button, button disappears for 2 seconds, text appears for 2 seconds and after those 2 seconds the visibility is reversed. So far I have done this:
btnScan.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
txtScanning.setVisible(true);
btnScan.setVisible(false);
try {
Thread.sleep(2000); //1000 milliseconds is one second.
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
btnScan.setVisible(true);
}
});
and the result is that as soon as I click the btnScan, the whole program freezes for 2 seconds before doing anything. How do I add the delay at the correct order?
You should not call sleep method in your code that dispatches the event. All the work related UI is handled by EDT(Event Dispatch Thread) and a sleep method will cause it to freeze and hence your Swing application will freeze.
To overcome it you should use a Timer. Run the timer and execute the UI manipulation using SwingUtilities.invokeLater so that it is handled by EDT.
import java.util.Timer;
// make it a member variable
Timer timer = new Timer();
........
public void actionPerformed(java.awt.event.ActionEvent evt) {
button.setVisible(false);
timer.schedule(new TimerTask() {
#Override
public void run() {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
button.setVisible(true);
}
});
}
}, 2000);
}
Currently in your code, you are causing the EDT (event dispatcher thread) to pause with the invocation of Thread.sleep
Performing any long running tasks in the EDT will cause your UI to freeze.
To achieve what you desire, use a SwingWorker thread to perform your actions
This might help: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
Swing is a single threaded environment, anything that blocks this thread will prevent it from processing new events, including repaint requests.
Swing is also not thread safe, meaning img you should never create or update the UI from outside the context of the EDT.
In this case you can use a Swing Timer to trigger a callback to occur at some time in the future which (the notification) will be executed within the context of the EDT, making it safe to update the UI with
Take a look at Concurrency in Swing and How to us Swing Timers for more details
Making use of Swing timer, you can do something like this:
btnScan.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
txtScanning.setVisible(true);
btnScan.setVisible(false);
Timer timer = new Timer(2000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent acv) {
btnScan.setVisible(true);
txtScanning.setVisible(false);
}
});
// setRepeats(false) to make the timer stop after sending the first event
timer.setRepeats(false);
timer.start();
}
});
I'm wondering how can I make a Java program delay parts of code to prevent spamming buttons/other things in the program. So let's just say I'm making a program that displays the amount of times a user has clicked a button. I would like there to be a delay to the user cannot click the button rapidly. I heard that java timers could help me, but I can't find any tutorial explaining what I need done.
public void ButtonActionPerformed(java.awt.event.ActionEvent evt) {
count+=1;
labelA.setText(Integer.toString(count));
}
This is just an example program, not what im actually working on. So can someone please help me? I need to have a program create a delay so the user cannot spam buttons. Thanks :) (this is a revised question from before)
If you have a field timer of javax.swing.Timer,
private Timer timer;
you can create the instance in the constructor or a init method:
final ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
button.setEnabled(true);
}
};
timer = new Timer(2000, listener);
timer.setRepeats(false);
In this case, the delay is 2000 miliseconds before enabling the button again.
You can start it in the click event of the button.
button.setEnabled(false);
timer.start();
Save an instance variable in your action listener called long lastClicked and initialize it to 0.
in your handler:
int delay = 1000;
if(System.currentTimeMillis() > lastClicked + delay)
{
//do your click
lastClicked = System.currentTimeMillis();
}
A delay of 1000 would be 1 second.
I have a dialog box that is:
JOptionPane.showMessageDialog(null,"Once medicine is given, measure temperature within 5 minutes." ,"Medication" ,JOptionPane.PLAIN_MESSAGE);
When the user presses 'ok', it goes straight to a Jframe that ask the user to input the temperature using a slider and then pressing a button that takes it to the next set of things.
Anyways, I want to create somekind of inivisble countdown after the user presses 'ok', so after 5 minutes of idleness on the Jframe menu, one warning dialog box should appear on top of the JFrame and says something like "NEED ATTENTION".
This reminds me of actionListener. but it will be invoked by non-physical element, 5 minutes, (not by any click of button).
So Maybe the code should be like:
JOptionPane.showMessageDialog(null,"Once medicine is given, measure temperature within 5 minutes." ,"Medication" ,JOptionPane.PLAIN_MESSAGE);
temperature_class temp = new temperature_class(); // going to a different class where the the Jframe is coded
if (time exceeds 5 minutes) { JOptionPane.showMessageDialog(null, "NEED attention", JOptionPane.WARNING_MESSAGE);}
else { (do nothing) }
Code works:
JOptionPane.showMessageDialog(null,"measure temp" ,"1" ,JOptionPane.PLAIN_MESSAGE);
int delay = 3000; //milliseconds
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
JOptionPane.showMessageDialog(null,"hurry." ,"Bolus Therapy Protocol" ,JOptionPane.PLAIN_MESSAGE); } };
new Timer(delay, taskPerformer).start();
temperature_class temp = new temperature_class();
However, I want it do it only once. So how do I invoke set.Repeats(false)?
You could use a TimerTask with a Timer:
class PopTask extends TimerTask {
public void run() {
JOptionPane.show...
}
}
then where you want to schedule your task:
new Timer().schedule(new PopTask(), 1000*60*5);
This kind of timers can also be canceled with cancel() method
Essentially, after the initial option pane is shown, start a Timer. (A javax.swing one)
You will also need a class-level variable indicating if the temp has been entered yet.
JOptionPane.showMessageDialog(...);
tempHasBeenEntered = false;
Timer tim = new Timer(5 * 60 * 1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!tempHasBeenEntered)
JOptionPane.showMessageDialog("Hey, enter the temp!!");
}
}
tim.setRepeats(false);
tim.start();
You will need to flip the flag once a user enters a temp into the form.
Read the section from the Swing tutorial on How to Use Timers. When the dialog is displayed you start the Timer. When the dialog is closed you stop the Timer.
A Swing Timer should be used, not a TimerTask so that if the Timer fires the code will be executed on the EDT.