Java animation stutters when not moving mouse cursor

后端 未结 4 2027
难免孤独
难免孤独 2020-12-05 05:06

I have a quite simple animation, a text in a big font moving continuously (pixel by pixel) to the left. The text is first converted to an image, then a timer task is started

相关标签:
4条回答
  • 2020-12-05 05:46

    Profiling shows that you are saturating the shared thread used by javax.swing.Timer. One mitigation strategy is to use a longer period and/or a larger increment/decrement, as shown here.

    Addendum: In addition, you are laboriously re-rendering the entire image in each call to paintComponent(). Instead, render it once using TextLayout, seen here, and draw() only the newly visible portion each time.

    image

    0 讨论(0)
  • 2020-12-05 05:53

    Try calling this method when you are done drawing:

     Toolkit.getDefaultToolkit().sync();
    

    This flushs the graphics buffer which some systems like Linux use. See the Javadoc: http://docs.oracle.com/javase/7/docs/api/java/awt/Toolkit.html#sync()

    0 讨论(0)
  • 2020-12-05 06:08
    • Don't, EVER, use getGraphics and you should NEVER call paintComponent yourself, this not how custom painting is done in Swing. Instead, update the state and call repaint.
    • Don't rely on magic numbers, use the information you have at hand (getWidth and getHeight)
    • Swing components are doubled buffered, so it's unlikely you would need to create you own buffered strategy. This simple act could be slowing down your painting
    • You must call super.paintComponent. This is even more important with JComponent, as it is not opaque and failing to do so could result in some nasty paint artefacts.
    • You should override JComponent#getPreferredSize so it can work with layout managers for efficiently.
    • You may find a shorter delay produces a better illusion, say 40 milliseconds (roughly 25fps) for example

    Take a look at Swing animation running extremely slow, which through some object management and optimisation, was able to increase from 500 animated objects up to 4500.

    Also take a look at Performing Custom Painting and Painting in AWT and Swing in particular

    0 讨论(0)
  • 2020-12-05 06:12

    Problem solved!

    To answer my own question: After realizing that any continuous input (mouse or keyboard) makes the animation run smoothly, I remembered that inputs can be generated by the program itself, using an object of the class java.awt.Robot. That lead to a simple workaround: Create a Robot and let it press a key or a mouse move in each animation cycle.

    final Robot robot = new Robot();
    javax.swing.Timer timer = new javax.swing.Timer(initialDelay, new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            // update your image...
    
            robot.keyPress(62);
         }
    });
    

    This is a kludge, but works perfectly.

    0 讨论(0)
提交回复
热议问题