【问题标题】:Java Animation programs running jerky in Linux在 Linux 中运行生涩的 Java 动画程序
【发布时间】:2017-04-21 11:04:45
【问题描述】:

我在 Ubuntu 14.4.1 中编写了一个简单的 Java 动画程序。一个球在 JPanel 内移动。但是在执行时,球在 JPanel 中的移动非常不稳定。这个问题一直持续到我将鼠标移到 JPanel 内。在 JPanel 内移动鼠标时,球的移动非常顺畅。应该说我在Windows 10中运行过这个程序,没有出现任何问题。我的程序代码如下:

import java.awt.*;
import javax.swing.*;

public class BouncingBall extends JPanel {
    Ball ball = new Ball();

    void startAnimation() {
        while( true ) {
            try {
                Thread.sleep( 25 );
                ball.go();
                repaint();
            } catch( InterruptedException e ) {}
        } // end while( true )
    } // end method startAnimation()

    protected void paintComponent( Graphics g ) {
        super.paintComponent( g );
        ball.draw( g );
    } // end method paintComponent


    // inner class Ball
    class Ball {
        int x;
        int y;
        int diameter = 10;
        int xSpeed = 100;
        int ySpeed = 70;

        void go() {
            x = x + (xSpeed*25)/1000;
            y = y + (ySpeed*25)/1000;

            int maxX = getWidth() - diameter;
            int maxY = getHeight() - diameter;
            if( x < 0 ) {
                // bounce at the left side
                x = 0;
                xSpeed = -xSpeed;
            } else if( x > maxX ) {
                // bounce at the right side
                x = maxX;
                xSpeed = -xSpeed;
            } else if( y < 0 ) {
                // bounce at the top side
                y = 0;
                ySpeed = -ySpeed;
            } else if( y > maxY ) {
                // bounce at the bottom size
                y = maxY;
                ySpeed = -ySpeed;
            } // end if-else block
        } // end method go()

        void draw( Graphics g ) {
            g.fillOval( x , y , diameter , diameter );
        } // end method draw
    } // end inner class Ball


    public static void main( String[] args ) {
        JFrame window = new JFrame();
        window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        BouncingBall animation = new BouncingBall();
        animation.setPreferredSize( new Dimension( 500 , 500 ) );
        animation.setBackground( Color.white );
        window.add( animation );
        window.pack();
        window.setVisible( true );

        animation.startAnimation();
    } // end method main
} // end class BouncingBall

有什么问题?我是否必须更改 Ubuntu 中的某些设置? 我还在 paintComponent 方法中添加了一些测试代码,如下所示:

protected void paintComponent( Graphics g ) {
    System.out.println( "paintComponent call number: " + counter );
    ++counter;
    super.printComponent( g );
    ball.draw( g );
}  

在类 MovingBall 中声明的可变计数器初始值为 0。我观察到,paintComponent 每秒的调用次数远远超过 JPanel 的实际刷新率。

【问题讨论】:

  • paintComponent 方法中的 println 会减慢它的速度,并且可能会产生明显的效果。你会想要它离开那里。
  • 主要问题出现在添加println之前。 println 语句只是一个测试语句,用于了解有关该问题的更多信息。
  • 我还会在您的动画方法中获得实时增量,并根据实时增量计算精灵的最佳位置。这样,无论动画是快还是慢,球都会移动相同的距离。
  • 我在linux下写的代码你执行了吗?
  • 没有。我在工作,我没有 Linux。

标签: java linux swing ubuntu animation


【解决方案1】:

视频加速在 Windows 中默认启用,但在 Linux 中默认未启用。 (这已经很多年了;我可以发誓这个默认值在最近的 Java 版本中被改变了,但显然我错了。)

您可以enable OpenGL 获得加速性能:

public static void main( String[] args ) {
    System.setProperty("sun.java2d.opengl", "true");

    JFrame window = new JFrame();

或者,您可以在命令行上设置属性:

java -Dsun.java2d.opengl=true BouncingBall

【讨论】:

  • 感谢您的回答。你说的两种方法我都试过了。但他们都没有解决这个问题。动画仍然像以前一样生涩。
  • 该属性对我产生了巨大的影响。你的 Linux 系统的显卡是什么?不知道它是否提供OpenGL加速?
  • 我不知道显卡和支持OpenGL。我怎样才能了解它们?
  • 等一下。它确实对我有用。我写错了 openg1 而不是 opengl。你说得对。但是现在还有另一个问题:如果我希望我的程序独立于平台,我是否必须将这个语句放在我所有动画或图形程序的开头?
  • 是的。您可能还想学习 JavaFX,它具有更好的性能并且不需要该属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-18
  • 1970-01-01
相关资源
最近更新 更多