技术开发 频道

JDK 7探秘二:半透明和任意形状的窗口

  半透明联合像素级透明和任意形状窗口

  你可以联合像素级半透明(或简单半透明)和像素级透明实现一个半透明的任意形状窗口,我创建了一个CTSWDemo程序演示这是可能的,清单4中的代码扩展了前面的例子,包括了像素级半透明代码。

  清单 4. CTSWDemo.java

// CTSWDemo.java
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Ellipse2D;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CTSWDemo extends JFrame
{
  
public CTSWDemo ()
   {
      
super ("Combined Translucency with Per-Pixel Transparency and Shaped "+
            
"Window Demo");
      setUndecorated (
true); // Avoid decorated window artifacts.
      JPanel gradPanel = new JPanel ()
                         {
                             Color colorA
= new Color (255, 0, 0, 0);
                             Color colorB
= new Color (255, 0, 0, 255);
                            
protected void paintComponent (Graphics g)
                             {
                                 Graphics2D g2d
= (Graphics2D) g;
                                 GradientPaint gp;
                                 gp
= new GradientPaint (0.0f, 0.0f, colorA,
                                                        
0.0f, getHeight (),
                                                         colorB,
true);
                                 g2d.setPaint (gp);
                                 g2d.fillRect (
0, 0, getWidth (),
                                               getHeight ());
                                
                             }
                         };
      gradPanel.setPreferredSize (
new Dimension (300, 200));
      gradPanel.setLayout (
new BoxLayout (gradPanel, BoxLayout.Y_AXIS));
      JButton btnClose
= new JButton ("Close");
      ActionListener al;
      al
= new ActionListener ()
           {
              
public void actionPerformed (ActionEvent ae)
               {
                  System.exit (
0);
               }
           };
      btnClose.addActionListener (al);
      btnClose.setAlignmentX (
0.5f);
      gradPanel.add (Box.createVerticalGlue ());
      gradPanel.add (btnClose);
      gradPanel.add (Box.createVerticalGlue ());
      setContentPane (gradPanel);
      
if (!getGraphicsConfiguration ().isTranslucencyCapable ())
      {
          System.err.println (
"per-pixel translucency not in effect for this "+
                              
"graphics configuration");
          System.exit (
0);
      }
      setBackground (
new Color (0, 0, 0, 0)); // Achieve per-pixel
                                              
// translucency.
      pack ();
      setShape (
new Ellipse2D.Float (0, 0, getWidth (), getHeight ()));
      setLocationRelativeTo (
null);
      setVisible (
true);
   }
  
public static void main (String [] args)
   {
      Runnable r;
      r
= new Runnable ()
          {
              
public void run ()
              {
                 GraphicsEnvironment ge;
                 ge
= GraphicsEnvironment.getLocalGraphicsEnvironment ();
                
if (!ge.getDefaultScreenDevice ().
                         isWindowTranslucencySupported
                           (GraphicsDevice.WindowTranslucency.
                                           PERPIXEL_TRANSLUCENT))
                 {
                     System.err.println (
"per-pixel translucency isn't "+
                                        
"supported");
                    
return;
                 }
                
if (!ge.getDefaultScreenDevice ().
                         isWindowTranslucencySupported
                           (GraphicsDevice.WindowTranslucency.
                                           PERPIXEL_TRANSPARENT))
                 {
                     System.err.println (
"per-pixel transparency isn't "+
                                        
"supported");
                    
return;
                 }
                
new CTSWDemo ();
              }
          };
      EventQueue.invokeLater (r);
   }
}

  上面的梯度代码在创建Color对象时再次使用了alpha值,如图4所示,但半透明红色梯度现在只占用了椭圆形部分,而不是整个窗口。

 半透明联合像素级透明和任意形状窗口

图 4 setBackground()方法调用允许椭圆形内用红色半透明呈梯度渲染

  小结

  JDK 7对半透明和任意形状窗口的支持使得创建富有新意的UI更为容易,希望正式发布时会包含软剪裁或其它可移除边缘锯齿的技术。下一篇文章将会介绍JDK 7中新出现的JLayer Swing组件。

0
相关文章