• 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
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Java Swing Timers & Threads &only last command is being executed in For Loop

 
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi everyone,

Hope you are all well.

Also I'm so sorry for how long winded this is. And I'm new to Java so please forgive me for my lack of knowledge/terminology/Java conventions.

Basically I've created a program which takes user input and moves the vehicle across the surface area. So the user input can be "50 left 4" so that means go 50 meters forward, turn left and go 4 meters forward. For the vehicle I'm using a paint method on a JPanel. When the vehicle moves forward, it initially jumped from one side of the area to another. I wanted to be able to see it moving meter by meter. So I added a Swing Timer which moves the vehicle 1 meter, pauses for a second, moves the vehicle 2 meter and so on.

Now, the problem is that when I enter the commands "50 left 4", the vehicle simply turns left and then moves 4 meters forward. It ignores the first number command. The same happens when I enter "3 4", it will ignore 3 and just move 4 meters forward. Also when I enter "3 left", it will turn left first and then move 3 meters forward. Now I've got methods which takes the user input, chop it up into an array, feed each element of the array through a loop, check if it's an integer or not. If it is an integer it moves the vehicle forward, if not it turns the vehicle either left or right. That all works fine and I'm happy with it.

So what I thought I'd do is have the class which moves the vehicle implement Runnable so that this method will be executed from a separate thread, making the main thread wait and that way it will won't ignore every command except for the last. But that doesn't work either.

Here is the movement class which moves the vehicle forward 1 meter at a time using a Swing Timer.
It implements Runnable.







And here is the code from another class which runs the for loop and thread:




I really appreciate you reading all that, thank you so much!

And thank you to anyone who replies! If you know where I'm going wrong and what I can do to fix it, you're an absolute lifesaver, I really appreciate it
 
Marshal
Posts: 28193
95
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Well, I don't like the way you have static members all over the place. I'm not sure whether that's anything to do with your problem but I would get rid of all the static declarations.

Anyway, you have an actionPerformed method in the first class. That should update your GUI, and I don't see where it's doing that.
 
Cathy McDuff
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

The method are static because I've added them to the ActionListener of a button. These 2 classes are part of several others.

The program works like this:
Enter commands for the vehicle to move into a text field. Click on the button which performs the commands one by one from a loop. The issue is the for loop doesn't wait for the timer to finish, the for loop just goes from first command to last within a second. That's why only the last command takes any actual affect on the vehicle. I need the for loop to somehow wait for the Timer to finish before going moving on.

I hope this makes sense.

Thank you.
 
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Paul is correct. The problem you are seeing is because all you data and methods are static. When the data is static it is shared between all instances. You are making multiple instances but they are all setting the same values so each time you create a new movement object you are reseting that value. Then when it runs all of the movement ends up seeing the same value. The first one does the movement and all the other movements see that it has already been completed so they don't redo the movement

You need to make all the variables and methods non static.
 
Cathy McDuff
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Steve,

Thank you for your reply.

So I've done what you advised, I've changed the method to non static. However when I'm calling these methods in other classes it states "Cannot make a static reference to the non-static method turnRight() from the type Movement" and it asking me to change the methods to static. Now I found that if I create an instance of the Movement class like so "Movement m = new Movement();" and then call the method like so "m.method();" it doesn't come up with an error. Is this the right way to go about it? Will I need to create an instance whenever I want to use a method? Is the a good way to code? What's a better way of doing of this or is this the only way?

Many thanks!
 
Cathy McDuff
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Steve,

So I've done what you asked and now the vehicle isn't moving at all. The vehicle is represented by an image which I move and turn using the rotate and translate methods from the Affine Transform class. Anyway the image isn't moving at all, it's not updating. I've got the repaint(); method and I have added super.paintComponent(g) to but the image does not do anything at all. The program runs but GUI isn't being updating. Any ideas? It looks like I might have to go back to static methods.

Thank you.
 
Rancher
Posts: 989
9
  • Likes 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Probably you are doing things on the GUI interface thread (EDT) that you shouldn't be doing, e.g calling join on it to wait for other threads. It's difficult to say for sure without seeing what your current code looks like now.
My advice would be to learn things about static/vs instance variables first before doing any threading or GUI stuff with swing.
 
Cathy McDuff
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

So it might be best to have the entire GUI on another thread and have the main thread wait until going through the next element in the loop?

Thank you!
 
Steve Luke
Bartender
Posts: 4179
22
IntelliJ IDE Python Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Cathy McDuff wrote:Hi,

So it might be best to have the entire GUI on another thread and have the main thread wait until going through the next element in the loop?

Thank you!



Your entire GUI must be in the Event Dispatch Thread, no choice on that matter. Your other work (the waiting and moving) cshould be done in another thread. Read this: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/
 
reply
    Bookmark Topic Watch Topic
  • New Topic