2012-08-15 65 views
2

我試圖使用GlassPane將圖標閃爍給用戶。我運行一個javax.swing.Timer基本上執行此:Java Swing - 閃爍的圖標不顯示

for (int i = 0; i < 3; i++) { 
    frame.getGlassPane().setVisible(true); 
    try { 
     Thread.sleep(500); 
    } catch (InterruptedException e1) { 
     //To change body of catch statement use File | Settings | File Templates. 
     e1.printStackTrace(); 
    } 
    frame.getGlassPane().setVisible(false); 
} 

不幸的是,如果我睡覺EDT(定時器內當前線程),該圖標不顯示,如paintComponent方法沒能得到充分調用在線程進入睡眠之前。因此,當下一條指令進入時,玻璃窗格被隱藏,結果,圖標從不顯示。有沒有一種方法可以使用這種(類似)方法實現我想要的功能?

+0

更多的例子[這裏](http://stackoverflow.com/a/2234020/230513)和[這裏](http://stackoverflow.com/a/2124507/230513)。 – trashgod 2012-08-15 10:39:03

回答

5

你可以使用一個javax.swing.Timer

public FlashTimer() { 

    javax.swing.Timer flashTimer = new javax.swing.Timer(500, new FlashHandler()); 
    flashTimer.setCoalesce(true); 
    flashTimer.setRepeats(true); 
    flashTimer.setInitialDelay(0); 

} 

public class FlashHandler implements ActionListener { 

    private int counter; 

    @Override 
    public void actionPerformed(ActionEvent ae) { 

     countrol.setVisible(counter % 2 == 0); 
     counter++; 
     if (counter > 3) { 

      ((Timer)ae.getSource()).stop(); 

     } 

    } 

} 
+0

心理筆記 - 你需要重新運行之間的'counter'; ) – MadProgrammer 2012-08-15 10:16:50

3

這應該是顯而易見的 - 使用一個單獨的線程,並做了「閃爍的邏輯」存在,但修改EDT的UI。下面是一個簡單的例子(應該是足夠的瞭解的想法):

public static void main (String[] args) 
{ 
    JFrame frame = new JFrame(); 

    final JLabel label = new JLabel ("X"); 
    label.setBorder (BorderFactory.createEmptyBorder (90, 90, 90, 90)); 
    frame.add (label); 

    frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); 
    frame.pack(); 
    frame.setLocationRelativeTo (null); 
    frame.setVisible (true); 

    new Thread (new Runnable() 
    { 
     public void run() 
     { 
      for (int i = 0; i < 15; i++) 
      { 
       try 
       { 
        setVisible (false); 
        Thread.sleep (500); 
        setVisible (true); 
        Thread.sleep (500); 
       } 
       catch (InterruptedException e1) 
       { 
        // 
       } 
      } 
     } 

     private void setVisible (final boolean visible) 
     { 
      SwingUtilities.invokeLater (new Runnable() 
      { 
       public void run() 
       { 
        label.setVisible (visible); 
       } 
      }); 
     } 
    }).start(); 
} 
+0

您可以簡單地通過使用javax.swing.Timer的過程 – MadProgrammer 2012-08-15 09:39:36

+0

@MadProgrammer我不能(如果我使用睡眠語句),因爲Timer操作體在EDT中執行。這就是爲什麼我使用單獨的線程。雖然它很容易用定時器不帶睡眠語句執行,但您只需在每個定時器事件中反轉元件可見性即可。無論如何,這兩種方法都是可能的,並且是正確的... – 2012-08-15 10:12:41

+0

你不需要睡眠與定時器,讓定時器照顧睡眠,只是響應的ActionEvent。 – MadProgrammer 2012-08-15 10:15:08