2013-02-10 45 views
0

我想在我的啓動畫面上製作自己的進度條。創建我的啓動畫面很簡單:初始屏幕進度條沒有繪製

的Java -splash:EaseMailMain.jpg Main.class (在Eclipse)

我的主要方法的第一行調用此:

new Thread(new Splash()).start(); 

這就是飛濺類:

public class Splash implements Runnable { 
    public volatile static int percent = 0; 
    @Override 
    public void run() { 
     System.out.println("Start"); 
     final SplashScreen splash = SplashScreen.getSplashScreen(); 
     if (splash == null) { 
      System.out.println("SplashScreen.getSplashScreen() returned null"); 
      return; 
     } 
     Graphics2D g = splash.createGraphics(); 
     if (g == null) { 
      System.out.println("g is null"); 
      return; 
     } 
     int height = splash.getSize().height; 
     int width = splash.getSize().width; 
     //g.drawOval(0, 0, 100, 100); 
     g.setColor(Color.white); 
     g.drawRect(0, height-50, width, 50); 
     g.setColor(Color.BLACK); 
     while(percent <= 100) { 
      System.out.println((width*percent)/100); 
      g.drawRect(0, height-50, (int)((width*percent)/100), 50); 
      percent += 1; 
      try { 
       Thread.sleep(50); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

我不得到任何錯誤,但我得到一個小盒子,它下面:

The image with a rectangle below.

如果我改變drawRects爲(0,0,寬,高),這都沒有區別。

我試過調用鞦韆EDT用:

SwingUtilities.invokeAndWait((new Splash())); 

但沒有任何反應。

任何人都可以看到問題嗎?或知道如何解決它?

+2

我不能嘗試這個(因此評論),但我會小心行:'(寬*百分比)/ 100',因爲這些都是對整數的操作。 – sdasdadas 2013-02-10 21:40:30

+0

這是一個有效的點,我會把100加倍。 – Adude11 2013-02-10 21:43:17

+0

你可以寫100.0。 – sdasdadas 2013-02-10 21:43:54

回答

4

從其他線程更新GUI時,應該使用SwingUtilities.invokeLaterSwingUtilities.invokeAndWait

請參閱章節Concurrency in Swing,其中解釋了背後的原因。

教程中的SplashScreen Example在Swing線程中執行Thread.sleep。如果您在顯示SplashScreen時不需要任何其他GUI刷新,那也可以。您的加載代碼應該發生在另一個線程中。

我建議在您的班級中添加一個setPercent二手設備,它會創建一個Runnable以通過SwingUtilities.invokeLater更新圖形用戶界面。這樣你甚至不需要輪詢percent變量,而SwingThread也可以自由渲染其他UI內容。

+0

哦,忘了補充一點,我已經測試過了,沒有區別。 – Adude11 2013-02-10 21:40:31

+1

@ Adude11從你的示例代碼中,不,你沒有,或者至少,沒有,你沒有做到這一點正確的...我已經延長了自行車的建議(+ 1),並試圖擴展你爲什麼'重新遇到麻煩。如果您覺得它有用,我會選擇適當的投票,但是您應該讚揚自行車運動員識別問題(標記他們的答案是正確的)。 – MadProgrammer 2013-02-10 23:38:11

3

Bikeshedder是正確的(+1),你阻止了EDT。

while(percent <= 100) { 
    System.out.println((width*percent)/100); 
    g.drawRect(0, height-50, (int)((width*percent)/100), 50); 
    percent += 1; 
    try { 
     Thread.sleep(50); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
} 

使用被放置Runnable到事件隊列中,當你進入你的while循環和Thread.sleep,你要阻止事件隊列調度,從任何新的事件,其中包括重繪請求

你應該意義使用類似於SwingWorker來執行實際加載(在後臺線程中),發佈啓動畫面可以顯示的進度結果...

enter image description here

public class TestSplashScreen { 

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

    public TestSplashScreen() { 
     SplashScreenWorker worker = new SplashScreenWorker(); 
     worker.execute(); 
     try { 
      worker.get(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
     System.out.println("All Done..."); 
//  Launch main application... 
//  SwingUtilities.invokeLater(...); 
    } 

    public class SplashScreenWorker extends SwingWorker<Void, Float> { 

     private SplashScreen splash; 

     public SplashScreenWorker() { 
      splash = SplashScreen.getSplashScreen(); 
      if (splash == null) { 
       System.out.println("SplashScreen.getSplashScreen() returned null"); 
       return; 
      } 
     } 

     @Override 
     protected void process(List<Float> chunks) { 
      Graphics2D g = splash.createGraphics(); 
      if (g == null) { 
       System.out.println("g is null"); 
       return; 
      } 
      float progress = chunks.get(chunks.size() - 1); 
      int height = splash.getSize().height; 
      int width = splash.getSize().width; 
      g.setComposite(AlphaComposite.Clear); 
      g.fillRect(0, 0, width, height); 
      g.setPaintMode(); 
      g.setColor(Color.WHITE); 
      g.drawRect(0, height - 50, width, 50); 
      g.setColor(Color.RED); 
      int y = height - 50; 
      g.fillRect(0, y, (int) (width * progress), 50); 
      FontMetrics fm = g.getFontMetrics(); 
      String text = "Loading Microsoft Windows..." + NumberFormat.getPercentInstance().format(progress); 
      g.setColor(Color.WHITE); 
      g.drawString(text, (width - fm.stringWidth(text))/2, y + ((50 - fm.getHeight())/2) + fm.getAscent()); 
      g.dispose(); 
      splash.update(); 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
      for (int value = 0; value < 1000; value++) { 

       float progress = value/1000f; 
       publish(progress); 
       Thread.sleep(25); 

      } 
      return null; 
     } 
    } 
}