2014-01-06 1 views
0

Я хотел создать программу, которая показывает некоторые изображения на экране вместе со строкой и анимацией. Я сделал это так:Java Timer повторяет, когда не следует

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), он всегда работает в два раза! В чем причина этого?

+0

У кого есть время, чтобы прочитать этот код? –

+0

Можете ли вы уменьшить код до минимального примера, который воспроизводит проблему? –

ответ

3
  1. Не выполняйте индивидуальную покраску на раме напрямую. Добавьте JPanel в рамку и переопределите метод paintComponent() панели для вашей пользовательской картины

  2. Не используйте Thread.sleep() в методе рисования.

  3. Не используйте цикл while в методе краски. Методы краски предназначены для рисования логики и не должны содержать программную логику

Не знаю, помогут ли эти предложения решить эту проблему, но ее место для начала.

Также графические объекты, переданные методам рисования, будут объектом Graphics2D, поэтому вам не потребуется проверка экземпляра.

+0

Черт побери! :) –