Java Timer会在不应该重复的情况下重复

时间:2014-01-06 17:15:50

标签: java swing fullscreen paint timing

我想制作一个程序,在屏幕上显示一些图片以及字符串和动画。我这样做了:

package Package;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class runScreen extends JFrame 
{
    public static void main(String[] arg) 
    {
        DisplayMode dm = new DisplayMode(1920, 1080, 16, DisplayMode.REFRESH_RATE_UNKNOWN);
        runScreen b = new runScreen();
        b.getContentPane().setBackground(Color.CYAN);
        b.startScreen(dm);
    }
    private Screen s;
    private Image logo;
    private Image animation1;
    private Image animation2;
    private Image animation3;
    private boolean isLoaded;
    private static int testTime=5000;
    public void startScreen(DisplayMode dm) 
    {
        setForeground(Color.blue);
        setFont(new Font("Agency FB", Font.PLAIN, 50));
        isLoaded=false;
        s=new Screen();
        s.setFullScreen(dm, this);
        loadGraphics();
        Timer timer = new Timer(testTime, new ActionListener() 
        {
            @Override
            public void actionPerformed(ActionEvent e) 
            {
                s.restoreScreen();
            }
        });
        timer.setRepeats(false);
        timer.start();
    }
    private void loadGraphics() 
    {
        logo= new ImageIcon("C:\\test\\Atom.png").getImage();
        animation1=new ImageIcon("C:\\test\\Red.png").getImage();
        animation2=new ImageIcon("C:\\test\\Green.png").getImage();
        animation3=new ImageIcon("C:\\test\\Blue.png").getImage();
        isLoaded=true;
        repaint();
    }
    public void paint(Graphics g) 
    {
        super.paint(g);
        if(g instanceof Graphics2D)
        {
            Graphics2D g2=(Graphics2D)g;
            g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        }
        if(isLoaded)
        {
            g.drawImage(logo,850,100,null);
            g.drawString("Atom", 900, 500);
            boolean canAnimationRun=true;
            int animationTime=0;
            while(canAnimationRun)
            {
                if(animationTime<testTime && canAnimationRun)
                {
                    g.drawImage(animation1,850,800,null);
                    try{Thread.sleep(1000);}
                    catch(Exception e){e.printStackTrace();}
                    animationTime+=1000;
                }else{canAnimationRun=false;}
                if(animationTime<testTime && canAnimationRun)
                {
                    g.drawImage(animation2,850,800,null);
                    try{Thread.sleep(1000);}
                    catch(Exception e){e.printStackTrace();}
                    animationTime+=1000;
                }else{canAnimationRun=false;}
                if(animationTime<testTime && canAnimationRun)
                {
                    g.drawImage(animation3,850,800,null);
                    try{Thread.sleep(1000);}
                    catch(Exception e){e.printStackTrace();}
                    animationTime+=1000;
                }else{canAnimationRun=false;}
            }
        }
    }
    public class Screen 
    {
        GraphicsDevice videoCard;
        public Screen() 
        {
            GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
            videoCard = env.getDefaultScreenDevice();
        }
        public void setFullScreen(DisplayMode dm, JFrame window) 
        {
            window.setUndecorated(true);
            window.setResizable(false);
            videoCard.setFullScreenWindow(window);
            if (dm!=null && videoCard.isDisplayChangeSupported()) 
            {
                try{videoCard.setDisplayMode(dm);}
                catch (Exception e){e.printStackTrace();}
            }
        }

        public Window getFullScreenWindow() 
        {
            return videoCard.getFullScreenWindow();
        }
        public void restoreScreen() 
        {
            Window w = videoCard.getFullScreenWindow();
            if (w != null) 
            {
                w.dispose();
            }
            videoCard.setFullScreenWindow(null);
        }
    }
}

但是时间有问题;即使我设置了它应该运行的时间(参见testTime),它总是运行两倍!这是什么原因?

1 个答案:

答案 0 :(得分:3)

  1. 不要直接在框架上进行自定义绘画。将JPanel添加到框架并覆盖自定义绘画面板的paintComponent()方法

  2. 不要在绘画方法中使用Thread.sleep()。

  3. 不要在paint方法中使用while循环。绘制方法用于绘制逻辑,不应包含程序逻辑

  4. 不知道这些建议是否会解决问题,但它是一个可以开始的地方。

    此外,传递给绘画方法的图形对象将是Graphics2D对象,因此您不需要执行instanceof检查。