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
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.
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()
getGraphics
and you should NEVER call paintComponent
yourself, this not how custom painting is done in Swing. Instead, update the state and call repaint
. getWidth
and getHeight
)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. JComponent#getPreferredSize
so it can work with layout managers for efficiently.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
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.