This week's book giveaway is in the Server-Side JavaScript and NodeJS forum.
We're giving away four copies of Node.js Design Patterns: Design and implement production-grade Node.js applications using proven patterns and techniques and have Mario Casciaro & Luciano Mammino on-line!
See this thread for details.
Win a copy of Node.js Design Patterns: Design and implement production-grade Node.js applications using proven patterns and techniques this week in the Server-Side JavaScript and NodeJS forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Ron McLeod
  • Rob Spoor
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Henry Wong
  • Liutauras Vilda
  • Jeanne Boyarsky
Saloon Keepers:
  • Jesse Silverman
  • Tim Holloway
  • Stephan van Hulst
  • Tim Moores
  • Carey Brown
Bartenders:
  • Al Hobbs
  • Mikalai Zaikin
  • Piet Souris

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

 
Ranch Hand
Posts: 39
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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"!
 
Bartender
Posts: 11445
19
Android Google Web Toolkit Mac Eclipse IDE Ubuntu Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
 
Marshal
Posts: 74085
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • 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 ?
 
Bartender
Posts: 4633
182
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
Bartender
Posts: 4633
182
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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
    Number of slices to send:
    Optional 'thank-you' note:
  • 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: 74085
332
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • 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.
 
You showed up just in time for the waffles! And this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
https://coderanch.com/wiki/718759/books/Building-World-Backyard-Paul-Wheaton
reply
    Bookmark Topic Watch Topic
  • New Topic