2013-02-16 100 views
0

我想要做的是讓它如此,當我運行我的應用程序,它啓動線程和圖像顯示3秒(3000毫秒),然後線程停止運行。這爲什麼不繪製圖像?

圖像的路徑是正確的,圖像文件存在,線程本身運行;然而,圖像似乎並沒有顯示出來。什麼可能是錯的?這裏是我的代碼:

package org.main; 

import java.awt.Graphics; 
import java.awt.Image; 

import javax.swing.ImageIcon; 
import javax.swing.JPanel; 

public class Splasher extends JPanel implements Runnable { 
    private static final long serialVersionUID = 1L; 
    Image image; 
    ImageIcon splash = new ImageIcon("res/splash.png"); 
    public static Thread DrawSplash = new Thread(new Splasher()); 

    public Splasher() { 
     setFocusable(true); 
     image = splash.getImage(); 
     repaint(); 
    } 
    boolean hasRan = false; 
    public void run() { 
     try { 
      System.out.println("Drawing Splash Screen"); 
      repaint(); 
      Thread.sleep(3000); 
      System.out.println("Repainted"); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void paint(Graphics g) { 
     g.drawImage(image, 0, 0, null); 
    } 

    public Image getImage() { 
     return image; 
    } 
} 
+0

我們不知道你如何實際使用這個類。發佈證明問題的[SSCCE](http://sscce.org/)。另外,爲什麼不使用JLabel來顯示圖像而不是自定義繪畫? – camickr 2013-02-16 21:04:57

+0

http://i.imgur.com/oVXif7c.png究竟如何,我會用一個JLabel – Jerba 2013-02-16 21:14:11

+0

@Jerba'#的JLabel setIcon' – MadProgrammer 2013-02-16 22:09:41

回答

2

有沒有足夠的去從你的問題。

如果連接到任何東西或者如何啓動/使用Thread,則不會顯示如何使用啓動畫面。

所以這個問題可能是什麼...

除了一切VishalK已經指出的那樣,我想補充public static Thread DrawSplash = new Thread(new Splasher())是一個壞主意。您不應該使用staticThread s是線程是不可重入的,也就是說,您可以運行兩次相同的線程。

這是一個小例子證明了「衰落」閃屏,採用了多項搖擺Timer小號

這裏假設你正在使用的Java 7,有去使它成爲Java 6的工作,我我沒有發佈該代碼。

public class TestSplashScreen01 { 

    public static void main(String[] args) { 
     new TestSplashScreen01(); 
    } 

    public TestSplashScreen01() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       SplashScreen splash = new SplashScreen(); 
       splash.start(); 

      } 
     }); 
    } 

    public class SplashScreen extends JWindow { 

     private SplashPane splash; 

     public SplashScreen() { 
      setBackground(new Color(0, 0, 0, 0)); 
      splash = new SplashPane(); 
      add(splash); 
      pack(); 
      setLocationRelativeTo(null); 
     } 

     public void start() { 
      splash.start(); 
     } 

     public class SplashPane extends JPanel { 

      private BufferedImage splash; 
      private Timer timer; 
      private float alpha = 0f; 
      private int duration = 1000; 
      private long startTime = -1; 

      public SplashPane() { 
       try { 
        splash = ImageIO.read(getClass().getResource("/res/SokahsScreen.png")); 
       } catch (IOException ex) { 
        ex.printStackTrace(); 
       } 
       timer = new Timer(3000, new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         fadeOut(); 
        } 
       }); 
       timer.setRepeats(false); 
      } 

      protected void fadeOut() { 
       Timer fadeInTimer = new Timer(40, new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         long now = System.currentTimeMillis(); 
         long runTime = now - startTime; 
         alpha = 1f - ((float) runTime/(float) duration); 
         if (alpha <= 0.01f) { 
          alpha = 0f; 
          ((Timer) (e.getSource())).stop(); 
          SwingUtilities.invokeLater(new Runnable() { 
           @Override 
           public void run() { 
            dispose(); 
           } 
          }); 
         } 
         repaint(); 
        } 
       }); 
       startTime = System.currentTimeMillis(); 
       fadeInTimer.setRepeats(true); 
       fadeInTimer.setCoalesce(true); 
       fadeInTimer.start(); 
      } 

      protected void fadeIn() { 
       Timer fadeInTimer = new Timer(40, new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         long now = System.currentTimeMillis(); 
         long runTime = now - startTime; 
         alpha = (float) runTime/(float) duration; 
         if (alpha >= 1f) { 
          alpha = 1f; 
          ((Timer) (e.getSource())).stop(); 
          timer.start(); 
         } 
         repaint(); 
        } 
       }); 
       startTime = System.currentTimeMillis(); 
       fadeInTimer.setRepeats(true); 
       fadeInTimer.setCoalesce(true); 
       fadeInTimer.start(); 
      } 

      public void start() { 
       if (!SplashScreen.this.isVisible()) { 
        alpha = 0f; 
        SplashScreen.this.setVisible(true); 
        SwingUtilities.invokeLater(new Runnable() { 
         @Override 
         public void run() { 
          fadeIn(); 
         } 
        }); 
       } 
      } 

      @Override 
      public Dimension getPreferredSize() { 
       return splash == null ? super.getPreferredSize() : new Dimension(splash.getWidth(), splash.getHeight()); 
      } 

      @Override 
      protected void paintComponent(Graphics g) { 
       super.paintComponent(g); 
       if (splash != null) { 
        Graphics2D g2d = (Graphics2D) g.create(); 
        g2d.setComposite(AlphaComposite.SrcOver.derive(alpha)); 
        int x = (getWidth() - splash.getWidth())/2; 
        int y = (getHeight() - splash.getHeight())/2; 
        g2d.drawImage(splash, x, y, this); 
        g2d.dispose(); 
       } 
      } 
     } 
    } 
} 

NB:

這個例子的問題是,一旦你打電話開始時,程序將繼續執行,這將需要某種聽者告訴有關方面,當閃屏已完成。

或者,你可以使用一個未加裝飾的模式JDialog

+0

+1 ..Always一個典型的例子繪製圖像! – 2013-02-17 07:51:27

1

,你在你的代碼已經做了很多的錯誤......

  1. 你重寫paint方法,而不是paintComponent繪製圖像。
  2. 您已使用Thread來繪製和刪除Swing組件(JPanel)上的圖像。您應該使用javax.swing.Timer
  3. 雖然您應該使用javax.swing.Timer,但您所做的基本錯誤仍然是您創建了一個靜態線程,並在其中傳遞了一個新對象Splasher而不是當前對象。
  4. 每次您想要對Component的圖形進行更改時,您應該明確地調用repaint。例如,如果您想讓圖像在3秒後消失,則應在3秒後調用repaint方法,並且應在paintComponent方法內寫入正確的邏輯以刪除該圖像。

這裏是你在找什麼for.Have上一看:

import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.event.ActionListener; 
import java.awt.event.ActionEvent; 
import java.awt.event.ComponentEvent; 
import java.awt.event.ComponentAdapter; 

import javax.swing.ImageIcon; 
import javax.swing.JPanel; 
import javax.swing.JFrame; 
import javax.swing.Timer; 
import javax.swing.SwingUtilities; 

public class Splasher extends JPanel { 

    private static final long serialVersionUID = 1L; 
    Image image; 
    ImageIcon splash = new ImageIcon("apple.png"); 
    MyComponentListener componentListener ; 
    Timer timer ; 

    public Splasher() 
    { 
     componentListener = new MyComponentListener(); 
     setFocusable(true); 
     image = splash.getImage(); 
     timer = new Timer(3000, new LoadAction()); 
     addComponentListener(componentListener); 
    } 
    boolean hasRan = false; 

    @Override 
    public void paintComponent(Graphics g) 
    { 
     super.paintComponent(g); 
     if (image == null && timer !=null) 
     { 
      g.clearRect(0, 0, getWidth(), getHeight()) ; 
      timer.stop(); 
      removeComponentListener(componentListener); 
     } 
     else 
     { 
      g.drawImage(image, 0, 0, null); 
     } 
    } 
    public Image getImage() 
    { 
     return image; 
    } 
    private class MyComponentListener extends ComponentAdapter 
    { 
     @Override 
     public void componentResized(ComponentEvent evt) 
     { 
      System.out.println("Resized.."); 
      timer.start(); 
     } 
    } 
    private class LoadAction implements ActionListener 
    { 
     public void actionPerformed(ActionEvent evt) 
     { 
      System.out.println("Drawing Splash Screen"); 
      repaint(); 
      image = null; 
      repaint(); 
      System.out.println("Repainted"); 
     } 

    } 
    public static void main(String st[]) 
    { 
     SwingUtilities.invokeLater (new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       JFrame frame = new JFrame("Splash:"); 
       frame.getContentPane().add(new Splasher()); 
       frame.setSize(300,500); 
       frame.setVisible(true); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      } 
     }); 
    } 
} 

而且關注在Java畫圖機制下面的教程你的代碼,這是做準確的修改版本。http://docs.oracle.com/javase/tutorial/uiswing/painting/closer.html

+0

我會謹慎使用'componentResized'的方法可稱爲快速連續幾次當第一次實現了組件。 – MadProgrammer 2013-02-16 22:11:14

+0

@MadProgrammer:我不像'componentResized'得到任何事件除了這些火災時自動'JFrame'是要遏制它會顯示出來。你能建議一些方法嗎? – 2013-02-17 07:53:09

+0

那麼,你有很多的選擇。你可以(像我一樣)要求用戶調用某種'start'方法,或者你可以使用'addNotify',當組件被添加到容器時調用。 – MadProgrammer 2013-02-17 08:01:35

相關問題