Results 1 to 19 of 19
  1. #1
    Fortu is offline Member
    Join Date
    Dec 2010
    Posts
    57
    Rep Power
    0

    Default 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.

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    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.

  3. #3
    Fortu is offline Member
    Join Date
    Dec 2010
    Posts
    57
    Rep Power
    0

    Default

    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();
      }
    }

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    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.

  5. #5
    Fortu is offline Member
    Join Date
    Dec 2010
    Posts
    57
    Rep Power
    0

    Default

    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.

  6. #6
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    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.

  7. #7
    Fortu is offline Member
    Join Date
    Dec 2010
    Posts
    57
    Rep Power
    0

    Default

    Oh.. Yep, I'm calling super.paint(g) from within the painComponent method rather than super.paintComponent(g). Thank you for that XD

  8. #8
    ozzyman's Avatar
    ozzyman is offline Senior Member
    Join Date
    Mar 2011
    Location
    London, UK
    Posts
    797
    Blog Entries
    2
    Rep Power
    4

    Default

    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);

  9. #9
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by ozzyman View Post
    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);
    It's probably not a good idea to use a java.util.Timer in place of a javax.swing.Timer for a Swing application as you run a risk of concurrency problems.

  10. #10
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    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()).

  11. #11
    Fortu is offline Member
    Join Date
    Dec 2010
    Posts
    57
    Rep Power
    0

    Default

    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 :)

  12. #12
    ozzyman's Avatar
    ozzyman is offline Senior Member
    Join Date
    Mar 2011
    Location
    London, UK
    Posts
    797
    Blog Entries
    2
    Rep Power
    4

    Default

    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

  13. #13
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

  14. #14
    ozzyman's Avatar
    ozzyman is offline Senior Member
    Join Date
    Mar 2011
    Location
    London, UK
    Posts
    797
    Blog Entries
    2
    Rep Power
    4

    Default

    Eastern Daylight Time? Eau de Toilette? Lol, whats EDT? Sorry

  15. #15
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by ozzyman View Post
    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

  16. #16
    ozzyman's Avatar
    ozzyman is offline Senior Member
    Join Date
    Mar 2011
    Location
    London, UK
    Posts
    797
    Blog Entries
    2
    Rep Power
    4

    Default

    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?

  17. #17
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by ozzyman View Post
    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?
    I'm sorry, I don't understand what you're asking. Can you restate your question?

  18. #18
    ozzyman's Avatar
    ozzyman is offline Senior Member
    Join Date
    Mar 2011
    Location
    London, UK
    Posts
    797
    Blog Entries
    2
    Rep Power
    4

    Default

    its okay i read it a bit deeper and i know what you're talking about now :)

  19. #19
    ra4king's Avatar
    ra4king is offline Senior Member
    Join Date
    Apr 2011
    Location
    Atlanta, Georgia, US
    Posts
    396
    Rep Power
    4

    Default

    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

  1. Replies: 6
    Last Post: 01-14-2011, 05:08 PM
  2. Acting Java as if it's C problem
    By reis3k in forum New To Java
    Replies: 13
    Last Post: 10-18-2010, 10:10 AM
  3. Help with actionPerformed
    By mayhewj7 in forum New To Java
    Replies: 8
    Last Post: 02-10-2009, 07:45 PM
  4. Help with actionPerformed Statements
    By wco5002 in forum New To Java
    Replies: 8
    Last Post: 03-26-2008, 05:02 AM
  5. actionPerformed problem
    By tomitzel in forum New To Java
    Replies: 1
    Last Post: 01-08-2008, 07:10 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •