I have problem referencing the Timer to the ActionListener class. I want to stop the timer after Java displays the dialog box that displays the time and starts again after clicking on "Yes".
This is what I currently have:
public class AlarmClock
{
public static void main(String[] args)
{
boolean status = true;
Timer t = null;
ActionListener listener = new TimePrinter(t);
t = new Timer(10000, listener);
t.start();
while(status)
{
}
}
}
class TimePrinter implements ActionListener
{
Timer t;
public TimePrinter(Timer t)
{
this.t = t;
}
public void actionPerformed(ActionEvent event)
{
t.stop(); //To stop the timer after it displays the time
Date now = Calendar.getInstance().getTime();
DateFormat time = new SimpleDateFormat("HH:mm:ss.");
Toolkit.getDefaultToolkit().beep();
int choice = JOptionPane.showConfirmDialog(null, "The time now is "+time.format(now)+"\nSnooze?", "Alarm Clock", JOptionPane.YES_NO_OPTION);
if(choice == JOptionPane.NO_OPTION)
{
System.exit(0);
}
else
{
JOptionPane.showMessageDialog(null, "Snooze activated.");
t.start(); //To start the timer again
}
}
}
However, this code gives a null pointer exception error. Is there any other way I can reference the Timer?
You have a chicken-and-egg problem here, since the constructors of both classes require a reference to each other. You need to break the cycle somehow, the easiest way would be to construct the Timer without a listener, then construct the listener, then add it to the timer:
t = new Timer(10000, null);
ActionListener l = new TimePrinter(t);
t.addActionListener(l);
Alternatively, you could add a setter to TimePrinter instead of passing the Timer to its constructor:
class TimePrinter implements ActionListener
{
Timer t;
public TimePrinter() {}
public setTimer(Timer t)
{
this.t = t;
}
and then do
TimePrinter listener = new TimePrinter();
t = new Timer(10000, listener);
listener.setTimer(t);
Either way the end result is the same.
Related
The following Timer works perfectly.
private static final Timer TICK_HOUR = new Timer(3600000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// ...
}
});
What I want to do is call the actionPerformed() manually. How can I achieve this?
The question seems unclear to the readers, I'll try to explain more.
Timer does some process hourly. I want to do it whenever I want without interfering the timer's process.
Short answer...
A much simpler (and better designed) solution would be, instead of...
private static final Timer TICK_HOUR = new Timer(3600000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("OK");
}
});
You should externalise the work the ActionListener does...
private static final Timer TICK_HOUR = new Timer(3600000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
doReallyImportantWorkEveryHour();
}
});
then you remove the Timer from the equation and you can call doReallyImportantWorkEveryHour when you want and solve the fundamental problem
Long Answer
So, let's start with...
private static final Timer TICK_HOUR = new Timer(3600000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("OK");
}
});
Creating a Timer this way, automatically registers a ActionListener with the Timer.
You then state:
What I want to do is call the actionPerformed() method inside the timer's ActionListener manually. How can I achieve this?
Which suggest you want try and do something like...
private static final Timer TICK_HOUR = new Timer(3600000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
TICK_HOUR.getActionListeners()[0].actionPerformed(null);
}
});
This could cause a NullPointerException, but more importantly, this will have an adverse affect on system performance, as there is no way that the ActionListener will know it shouldn't continuously all itself - basically and infinite loop.
IF however, you wanted to, prematurely, trigger the Timers ActionListeners (outside of any registered listeners)
Then yes, you could use...
ActionEvent evt = new ActionEvent(
TICK_HOUR,
0,
TICK_HOUR.getActionCommand(),
System.currentTimeMillis(),
0);
for (ActionListener listener : TICK_HOUR.getActionListeners()) {
listener.actionPerformed(evt);
}
but make sure you're calling them from within the context of the EDT, as that's one of the guarantees that the Timer makes.
A "simpler" solution might be just to use the functionality that is already provide by the Timer itself...
public class ManuallyTimer extends Timer {
public ManuallyTimer(int delay, ActionListener listener) {
super(delay, listener);
}
public void tigger() {
ActionEvent evt = new ActionEvent(TICK_HOUR, 0, TICK_HOUR.getActionCommand());
fireActionPerformed(new ActionEvent(this, 0, getActionCommand(),
System.currentTimeMillis(),
0));
}
}
Inside a static-initializer-block store ActionListener in a variable instead of passing it directly to the Timer:
private static final Timer TICK_HOUR;
static{
ActionListener listener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// ...
}
};
TICK_HOUR = = new Timer(3600000, listener);
listener.actionPerformed(/* someEvent */);
}
You might aswell store the listener variable as a class level static variable and then call it elsewhere from your code:
private static final ActionListener LISTENER = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
// ...
}
};
private static final Timer TICK_HOUR = new Timer(3600000, LISTENER);
And then somewhere in your code
LISTENER.actionPerformed(/* someEvent */);
Use getActionListeners().
Returns an array of all the action listeners registered on this timer.
Returns:
all of the timer's ActionListeners or an empty array if no action listeners are currently registered.
~Java doc~
TICK_HOUR.getActionListeners()[0].actionPerformed(null);
This will throw a ArrayIndexOutOfBoundsException if there are no ActionListeners registered to the timer. So better check the length of the array before using.
I obviously am having problems with my understanding of interfaces/ listeners in Java. (Java newbie alert at red).
Using https://docs.oracle.com/javase/7/docs/api/javax/swing/Timer.html and interface examples, I am getting behaviour I do not understand from timer.stop, and/ or removing actionlisteners from the timer (I.e. firing the 'tick').
Whatever I do, I cannot stop the timer when using an interface etc- I can only get it to work in local classes = spaghetti code.
public void actionPerformed(ActionEvent e) {
SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");
JButton clicked= (JButton) e.getSource();
ClockLabel mainsClockList= new ClockLabel(mainsLab);
if (clicked==clock1But) {
///////// Clock not started
if (mainsRunning==false) {
//mainsClockList = new ClockLabel(mainsLab); // that starts
// it, wait for FB in listnr
mainsClockList.setStopWatchListener(new StopWatchListener() {
public void clockCount(long count) {
System.out.println("Clock fired"); // fired every
//click- should only be on attach
// multiple calls button or EL?
mainsLab.setText(sdf.format(count));
}
});
clock1But.setText("Stop");
mainsRunning=true;
}
//// clock already started
else if (mainsRunning== true) {
System.out.println("in butt pressed already run");
mainsClockList.stopClock();
mainsClockList.setEnabled(false);
mainsRunning=false;
}
}
else if (clicked==clock2But) {
System.out.println("Got 2nd but"); }
else if (clicked==clock3But) {
System.out.println("Got 3rd but"); }
}
the Clock Lab class stuff:-
public ClockLabel(JLabel labIn) {
sdf = new SimpleDateFormat("mm:ss");
t= new Timer(500, this );
t.start();
}
public void actionPerformed(ActionEvent e) {
// this is listener for t....
Date d= new Date();
long diff= d.getTime() -cStarted.getTime();
swListener.clockCount(diff);
}
public void stopClock() {
System.out.println("In CL, called stopclock");
t.stop(); // no effect
swListener= null; // no effect
System.out.println("swListener := null");
// swListener.wait(5000); null pointer on try catch so
//has killed sw....!
}
public void setStopWatchListener(StopWatchListener listener) {
this.swListener= listener;
}
}
Interface
public interface StopWatchListener {
public void clockCount(long count);
}
I have tried to minimise code but keep comments in to help. Thanks for any pointers, much appreciated.
System out is as follows with only 1 click on button to start, and one to stop:
Clock fired
Clock fired
Clock fired
Clock fired
in butt pressed already run
In CL, called stopclock
swListener := null
Clock fired
Clock fired
Clock fired
Clock fired
I need to display output to a JTextArea one character at a time, with a slight delay between each character. My attempt is as follows:
private static void printInput(final String input)
{
Timer timer = new Timer(60,new ActionListener(){
public void actionPerformed(ActionEvent e)
{
for(int i = 0; i<input.length(); i++)
{
messageArea.append(Character.toString(input.charAt(i)));
}
}
});
}
There are similar questions however I could not find one with an example I could use to figure out my problem
A Timer is a pseudo loop, that it is, it triggers an cycle after a predefined delay, each cycle is an iteration of the loop and each iteration you need to update the UI and update the iterator value.
Now, because I don't like working in the static context, the first thing I suggest is you wrap up the basic concept into a separate class. This way you can easily encapsulate the state
public class TypeWriter {
private Timer timer;
private int characterIndex = 0;
private String input;
private JTextArea textArea;
public TypeWriter(JTextArea textArea, String input) {
this.textArea = textArea;
this.input = input;
timer = new Timer(60, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (characterIndex < input.length()) {
textArea.append(Character.toString(input.charAt(characterIndex)));
characterIndex++;
} else {
stop();
}
}
});
}
public void start() {
textArea.setText(null);
characterIndex = 0;
timer.start();
}
public void stop() {
timer.stop();
}
}
So, this is pretty basic, all this does is, using a Timer, check to see if there are any more characters that need to be printed, if there is, it takes the next character and appends it to the text area and updates the iterator value. If we're at the end of the text, it will stop the Timer (ie, the exit condition)
I am trying to create a search bar which will search the entered string or character from db. While first character is typed in textfield it should wait for next 200ms, if next character is entered within that time then it will restart the counter and again wait for next 200ms if not, then it will search from db.
Here is some code which i tried but not work for me
#FXML protected void keyReleased(KeyEvent evt)throws Exception {
if (evt.getCode() != KeyCode.BACK_SPACE) {
String ch = evt.getText();
String[] myArray = new String[5];
run();
searchFrmDb(ch, myArray);
}
}
public void run(){
for(int i=1;i<5;i++){
try{
Thread.sleep(200);
}catch(InterruptedException e){System.out.println(e);}
System.out.println(i);
}
}
public void searchFrmDb(String ch,String[] myArray){
//db search operation ...
}
I am new in java help me out to sort out my problem
What should i use thread or Timer or anything else
Consider using a PauseTransition for functionality like this.
public class ControllerClass {
private final PauseTransition pauseBeforeSearch = new PauseTransition(Duration.millis(200));
#FXML protected void keyReleased(KeyEvent evt)throws Exception {
if (evt.getCode() != KeyCode.BACK_SPACE) {
pauseBeforeSearch.setOnFinished(e -> {
searchFrmDb(evt.getText(), new String[5]);
});
pauseBeforeSearch.playFromStart();
}
}
}
I would have a look at java.util.Timer and java.util.TimerTask:
class SearchTimerTask extends TimerTask{
#Override
public void run(){
searchFrmDb();
}
#Override
public void cancel(){
super.cancel();
//handle cancellation logic if necessary
}
}
Keep a reference to a Timer and a TimerTask somewhere:
Timer timer = new Timer();
TimerTask task;
Then in your key event handler you simply cancel the current task if there is one and fire up a new one:
#FXML protected void keyReleased(KeyEvent evt)throws Exception {
if (evt.getCode() != KeyCode.BACK_SPACE) {
if(task != null){
task.cancel();
task = new SearchTimerTask();
}
timer.schedule(task, 200);
}
}
I am making a simple target shooting game.I have a countdownTimer inside the label and an object that blinks in a random position inside the panel. Every time I click on the object,. the object's timer stops which makes that object stop too, but the countdown timer doesn't and that is my problem. I want the countdown timer should stop also.
Could someone help me about this matter?
Here's the code :
private void starting()
{
new Timer(TIMER_PERIOD, new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
if (count++ < MAX_COUNT)
{
String text = "Time remaining: (" + (MAX_COUNT - count) + ") seconds left";
setCountDownLabelText(text);
Date date = new Date();
setCountDownPanelText(date);
}
else
{
((Timer) e.getSource()).stop();
randomTimer.stop();
JOptionPane.showMessageDialog(null, "Game Over");
System.exit(0);
}
}
}).start();
}
It strikes me that you don't understand the code at all, that you are unaware of the anonymous class created that is extending Timer, which (if you'd seen the documentation) has a function stop() which does what you ask.
You need to store a reference to the Timer.
private javax.swing.Timer timer;
private void starting() {
timer = new Timer(TIMER_PERIOD, new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
// do stuff
// stop the timer
timer.stop();
// do other stuff
}
}
}