2012-09-21 69 views
3

我知道我可以淡入面板,通過將alpha值添加到背景顏色&一個計時器。但是,我怎樣才能淡入帶有子組件的面板(如JLabel)?我如何淡入JPanel和兒童?

EDIT

_fadeTimer = new Timer(40, new ActionListener() { 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      if (_alpha == 255) { 
       _fadeTimer.stop(); 
      } else { 
       pnl_hint.setBackground(new Color(
         bgColor.getRed(), 
         bgColor.getGreen(), 
         bgColor.getBlue(), 
         (_alpha += 1))); 

       pnl_hint.updateUI(); 
      } 
     } 
    }); 
    _fadeTimer.start(); 

回答

5

另一個選擇是捕獲面板的屏幕截圖,然後讓它用漸增的alpha複合來繪製自己。

這裏是一個小的演示(雖然我不知道這是真的很乾淨):

import java.awt.AlphaComposite; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JTextField; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

public class TestFading { 

    private static class FadingPanel extends JPanel { 
     private BufferedImage buffer; 
     private boolean isFading = false; 
     private long start; 
     private float alpha = 1.0f; 

     @Override 
     public void paint(Graphics g) { 
      if (isFading) {// During fading, we prevent child components from being painted 
       g.clearRect(0, 0, getWidth(), getHeight()); 
       ((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); 
       g.drawImage(buffer, 0, 0, this);// We only draw an image of them with an alpha 
      } else { 
       super.paint(g); 
      } 
     } 

     public void fade(int time) { 
      start = System.currentTimeMillis(); 
      buffer = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); 
      this.print(buffer.getGraphics());// Draw the current components on the buffer 
      isFading = true; 
      final int timeInMillis = time * 1000; 
      final Timer t = new Timer(50, null); 
      t.addActionListener(new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        long elapsed = System.currentTimeMillis() - start; 
        if (elapsed > timeInMillis) { 
         start = 0; 
         isFading = false; 
         buffer = null; 
         repaint(); 
         t.stop(); 
        } else { 
         alpha = 1.0f - (float) elapsed/timeInMillis; 
         repaint(); 
        } 
       } 
      }); 
      t.start(); 
     } 
    } 

    protected void initUI() throws MalformedURLException { 
     JFrame frame = new JFrame(TestFading.class.getSimpleName()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     final FadingPanel panel = new FadingPanel(); 
     JTextField textfield = new JTextField(60); 
     JLabel image = new JLabel(new ImageIcon(new URL("http://helios.gsfc.nasa.gov/image_mag_stamp.jpg"))); 
     JButton button = new JButton("Fade"); 
     button.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       // I use an invoke later to allow the button to release itself 
       SwingUtilities.invokeLater(new Runnable() { 

        @Override 
        public void run() { 
         panel.fade(5);// Fade the panel in 5s. 
        } 
       }); 
      } 
     }); 
     panel.add(textfield); 
     panel.add(image); 
     panel.add(button); 
     frame.add(panel); 
     frame.setSize(400, 300); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        new TestFading().initUI(); 
       } catch (MalformedURLException e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

} 
+0

我的JPanel不是不透明並具有青色背景色,但是當我調用'fade'時,它又變得不透明瞭並失去了它的背景顏色。最後,當「面部」完成時,面板會自行恢復。 –

3

未測試的僞代碼。

public void fade(Container c) { 
    Component[] children = c.getComponents(); 
    for (Component component : components) { 
     // do fade thing with component 
     if (component instanceOf Container) { 
      fade((Container)component); 
     } 
    } 
} 
+0

推倒它的邏輯使用遞歸方法...但我有我有一個ImageIcon面板的JLabel ......我不能讓他們像透明panel.setBackground(新顏色(紅,綠,blue,alpha); –

+1

這是一個'10部分'的問題,我們可以通過分期獲得線索嗎?爲了更快地獲得更好的幫助,請發佈[SSCCE](http://sscce.org /)。 –

+0

示例代碼張貼在上面! –

3

而不是設置背景覆蓋paintChildren方法。撥打super.paintChildren(),然後用半透明顏色填充組件的矩形。

+0

你可以舉一個代碼示例,關於如何用半透明顏色填充組件的矩形... pls :) –

0

我加了一個JLabel與圖像和不透明的JPanel設置爲false!

在overriden paintComponent方法中,我在super.paintComponent()調用之前設置了AlphaComposite和我的alpha。

How do I fade an image in swing?