Results 1 to 19 of 19
Thread: actionPerformed acting strangely
- 04-08-2011, 09:37 PM #1
Member
- Join Date
- Dec 2010
- Posts
- 57
- Rep Power
- 0
actionPerformed acting strangely
In a game that I've begun to develop, I'm implementing ActionListener on my custom JPanel class, and using Swing's Timer class to do my actionPerformed code, but I've hit a fairly serious problem:
Whenever I run the game, my character (2D aerial view) moves twice as slow in game when I do not have Firefox open. When I open Firefox, things speed up substantially.
I know that the problem lies in the Timer somewhere, but I can't figure out why this would happen. Firefox is my default browser.
If anyone wants to see code, then leave a comment and I'll get it on here.
-
How can anyone begin to guess what the problem is without seeing code? But no one wants to see a huge code post I'll bet. Your best bet for having us understand your problem and better be able to help you is to create and post an SSCCE. The process of creating this will help you to isolate the problem as well.
- 04-08-2011, 09:47 PM #3
Member
- Join Date
- Dec 2010
- Posts
- 57
- Rep Power
- 0
You have a point. I guess I forgot to make it clear that I wanted to know if anyone knew that this was a common problem or if I've just done something magnificently idiotic so my game will behave in such a way.
Here's the code:
Java Code:import java.awt.*; import javax.swing.*; import java.awt.event.*; public class c extends JPanel implements ActionListener { public Player player; public Timer timer; public InputMap inputmap; public ActionMap actionmap; public int f = 0; Action moveright = new AbstractAction() { public void actionPerformed(ActionEvent e) { player.moveRight(e); //player.moveRight(e); takes an action event, does nothing with } // the action event, and increases an int that keeps track of the x position by 1. }; // 7 more Actions defined here in the actual source code. public c() { setFocusable(true); setBackground(Color.BLACK); setDoubleBuffered(true); player = new Player(); inputmap = getInputMap(WHEN_IN_FOCUSED_WINDOW); inputmap.put(KeyStroke.getKeyStroke("D"), "one"); //more puts on inputmap, look similar to the one above actionmap = getActionMap(); actionmap.put("one", moveright); //more similar puts on actionmap as well timer = new Timer(5,this); timer.start(); } public void paint(Graphics g) { super.paint(g); Graphics2D g2d = (Graphics2D) g; g2d.drawImage(player.getMap(),player.mapX(),player.mapY(),this); g2d.drawImage(player.getImage(),player.getX(),player.getY(),this); Toolkit.getDefaultToolkit().sync(); g.dispose(); } public void actionPerformed(ActionEvent e) { player.move(); repaint(); } }
-
Some random thoughts
- Wouldn't you be better off doing your animation inside of the paintComponent method of the JPanel rather than paint as you lose all Swing benefits such as double buffering.
- Are you sure that you want to dispose the Graphics object passed into the paint/paintComponent method? I always thought that that was dangerous.
- I've never used the sync() method and have no idea what effect it might have. Does removing it change things?
- You'll probably want to base the position of your sprites based on elapsed time obtained from the system time. That way, even if your program's timer loop runs slow, the graphics speed is relatively invariant.
- Again, if you want better advice, you'll want to take the time and effort to create and post an SSCCE.
- 04-08-2011, 10:16 PM #5
Member
- Join Date
- Dec 2010
- Posts
- 57
- Rep Power
- 0
Now this is interesting:
I've begun to go through your random thoughts, and try each individually, but as soon as I overrode paintComponent() rather than paint(), the JPanel does not appear in my JFrame (I can see clear through the JFrame) and I get infinite "exception in thread awt-eventqueue-0 java.lang.stackoverflowerror" from swing's RepaintManager, which is pointing to JComponent's paint method. I'm baffled.
-
Are you calling super.paint(g) from within the paintComponent method rather than super.paintComponent(g)? Otherwise we really need an SSCCE to properly help you.
- 04-08-2011, 10:23 PM #7
Member
- Join Date
- Dec 2010
- Posts
- 57
- Rep Power
- 0
Oh.. Yep, I'm calling super.paint(g) from within the painComponent method rather than super.paintComponent(g). Thank you for that XD
-
If you want to know if there is a problem with the timer, try writing it another way and see if the problem persists.
Java Code:java.util.Timer timer = new java.util.Timer(); timer.scheduleAtFixedRate(new java.util.TimerTask() { public void run() { player.moveRight(); } }, 500, 500);
-
-
Also, 5 ms may be asking too much of the timer speed. But again, I suggest that you base your sprite's position on the real-time speed by multiplying speed by elapsed time (as obtained from the System.currentTimeMillis()).
- 04-08-2011, 11:18 PM #11
Member
- Join Date
- Dec 2010
- Posts
- 57
- Rep Power
- 0
Not disposing the graphics object seems to lessen random stops in movement while playing (I'll be moving my character and he'll pause for a little bit).
Not using sync() also lessens random stops. Both not being used at the same time nearly eliminates all stops, though this isn't the problem. Oh, yes, ever since I started recompiling, the game runs as fast as it's supposed to again. I don't know why.
I've also re-written a few parts of code, so that the JFrame subclass I have is now using a util timer to communicate with a server rather than a Swing Timer. I forgot that all swing timers execute on the same thread. So far, no problems such as those described above. I'll post again if they re-appear.
Also, I'll try that System.currentTimeMillis() idea out. I like the thought.
And thank you, Fubarable, you always comment so quickly and give such good responses :)
-
Fu: I thought that each util Timer runs in its own thread. What kind of concurrency problems happen?
Fortu: use timer.stop() when you're done with it, 'timer' being the variable name you assigned the timer to ofcourse
-
@ozzy: the Swing Timer guarantees that the code in the timer is run on the EDT while the util Timer does't.
-
Eastern Daylight Time? Eau de Toilette? Lol, whats EDT? Sorry
-
It's the Event Dispatch Thread or the main Swing thread, the one that's responsible for user interaction and gui painting. Please have a look here: Lesson: Concurrency in Swing
-
okay i read it, but when this tutorial mentions thread interference, isn't it talking about Swing object methods exclusively? what i'm getting at is, it should be okay for normal computations?
-
-
its okay i read it a bit deeper and i know what you're talking about now :)
- 04-10-2011, 04:07 AM #19
Toolkit.getDefaultToolkit().sync() syncs the graphics with your computer screen's refresh rate, aka V-SYNC.
If your problem is browser-dependent, then that means the slowdown is with Swing Timer. Unless you are doing critical calls that affect Swing GUI components, I strongly recommend NOT to use the Swing Timer.
What's recommended is to make your own game loop, use java.awt.Canvas instead of JPanel, and use BufferStrategy for drawing. No need to even use Swing at all.
Similar Threads
-
Can you help with this class? Boolean variables acting weird
By jazzermonty in forum New To JavaReplies: 6Last Post: 01-14-2011, 04:08 PM -
Acting Java as if it's C problem
By reis3k in forum New To JavaReplies: 13Last Post: 10-18-2010, 09:10 AM -
Help with actionPerformed
By mayhewj7 in forum New To JavaReplies: 8Last Post: 02-10-2009, 06:45 PM -
Help with actionPerformed Statements
By wco5002 in forum New To JavaReplies: 8Last Post: 03-26-2008, 04:02 AM -
actionPerformed problem
By tomitzel in forum New To JavaReplies: 1Last Post: 01-08-2008, 06:10 PM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks