• Post Reply Bookmark Topic Watch Topic
  • New Topic

I can't figure out why my timer is not working  RSS feed

 
Sami Kassoum
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I just wanted to play arround with timers to see how they work.
I wrote a programethat will write my name 30 times, with each new line I increment the space " " by 1 at the beginning
the desired  output  - see the code comments below -

 
but my code is not working althout it seems to be "perfect"!
 
Maneesh Godbole
Bartender
Posts: 11445
18
Android Eclipse IDE Google Web Toolkit Java Mac Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sami Kassoum wrote:I wrote a programethat will write my name 30 times, with each new line I increment the space " " by 1 at the beginning




This does NOT print an empty white space. For that use

Notice the white space between the quotes

Your code inside actionPerformed is executed every time as one block.
Result: It keeps executing indefinitely because the values of i and j get initialized to 0 everytime
Solution: (One of the many) Let the timer execute only once.

Note: Actually you don't need a timer for this. A simple nested loop will do
 
Campbell Ritchie
Marshal
Posts: 56546
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Have you read the documentation for Timer? It points out there is another Timer class, which it suggests is better, and there are two tutorials links.
This is obviously an exercise to see how a Swing timer works, and to see how nested loops work. I would suggest there is a more elegant way to print those spaces with a StringBuilder(←link) and its insert method; you can insert the space at position 0 (beginning of the text) and print out the StringBulder, which indirectly calls its toString() method. Now that Java8 is here (it is getting on for three years old), you can shorten that code greatly by deleting lots of boilerplate in the anonymous class, and convert it to a λ. It would be so much easier to create a λ if your action performed method contained one line.
The addActionListener method only takes an action listener as a parameter, so the compiler can predict the type of argument passed. The action listener interface has one method, so the compiler knows in advance you have to call that method. It also knows that method takes one parameter, and what type that parameter is, so you can miss out the method name and the parameter's type. You can only create λs from interfaces with one abstract method.
Timer writeName = new Timer(1000,new ActionListener() {
    @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < 30; i++){
                    for (int j = 0; j < i; j++){
                        System.out.print("");
                    }
                System.out.println("sammy");              
            }
        }
    });

Strike out unnecessary boilerplate:-
Timer writeName = new Timer(1000,new ActionListener() {
    @Override
            public void actionPerformed(ActionEvent e) {
                for (int i = 0; i < 30; i++){
                    for (int j = 0; j < i; j++){
                        System.out.print("");
                    }
                System.out.println("sammy");              
            }
        }
    });

Delete struck‑out code and excess spaces:-
Timer writeName = new Timer(1000, e {
    for (int i = 0; i < 30; i++){
        for (int j = 0; j < i; j++){
            System.out.print("");
        }
    System.out.println("sammy");              
});

That won't compile because you need something after e, viz the arrow token -> :-
Timer writeName = new Timer(1000, e -> {
    for (int i = 0; i < 30; i++){
        for (int j = 0; j < i; j++){
            System.out.print("");
        }
    System.out.println("sammy");              
});

If you had a one‑line method, you could dispense with the {} and ; inside the λ. Let's see if I can't write something with a string builder:-You need the counter class because I want to count up to 30, and I cannot use a local int variable because local variables used by λs must be “effectively final”. I shall mark any local variables final, just to be sure. I think that is better than declaring count as a field, which doesn't have to be final.I think that code shou‍ld work. It might be better to replace the block in lines 4‑12 with a method call, but you would have to pass the timer, the StringBuilder and the Counter as arguments to that method, so let's leave the code unchanged as it stands there.
 
Sami Kassoum
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think somthing mesterius happen when using loops inside timers! I still don't figure this out! or maybe Timers cannot type to the standard output ?
I changed the code with a new one as campbell advised - Thanks   - but I still can't run it , it says that the timer needs to be initialize.
here is the code :-

a question for the final declaration too

if builder is final how could it be changed each timer event ?
 
Piet Souris
Master Rancher
Posts: 2044
75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You are using a Swing Timer, and that means that the ActionListener is executed on the EDT. However, you do not activate the EDT. Now, I'm not sure what is happening here, but if you first invoke the EDT, then the program functions as it should. For instance:

I have never used the other Timer (see the API, the java.util.Timer, but I think that you should use that one. (the one that needs a TimerTask in the constructor). Let us know your findings!
 
Piet Souris
Master Rancher
Posts: 2044
75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hmm...
Piet wrote:writeName.start();   // a way to stop would be handy!

Stops by itself, after a while. Not sure what's going on here.
 
Sami Kassoum
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
yes it works now!
yes you are right there is a defference between javax.swing.Timer and java.util.Timer
but I have never seen such a syntax
where can I get more information about it ?
 
Campbell Ritchie
Marshal
Posts: 56546
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You can go through the Java™ Tutorials and look for the section about lambda expressions and method references, as well as the details of Swing threading. The SamiKassoum::new construct is a method reference, but there isn't a method called new. There can't be, because new is a keyword. When the introduced method references, they enhanced them by using ::new for calling a (no‑arguments) constructor.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!