2012-05-02 142 views
4

我想要做的JFrame边框透明的,所以我想这样做,用我自己的边框类...半透明的JFrame边境

private class ShadowBorder extends AbstractBorder { 

    private static final int RADIUS = 30; 

    @Override 
    public boolean isBorderOpaque() { 
     return false; 
    } 

    @Override 
    public Insets getBorderInsets(Component c) { 
     return new Insets(RADIUS, RADIUS, RADIUS, RADIUS); 
    } 

    @Override 
    public Insets getBorderInsets(Component c, Insets insets) { 
     insets.top = RADIUS; 
     insets.left = RADIUS; 
     insets.bottom = RADIUS; 
     insets.right = RADIUS; 
     return insets; 
    } 

    @Override 
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
           RenderingHints.VALUE_ANTIALIAS_ON); 
      g2d.setColor(new Color(0x66000000, true)); 

      g2d.fillRect(0, 0, width - RADIUS, RADIUS); 
     } 
} 

但边框不是透明的决赛。边界内部也有白色背景,但我不知道为什么(请参阅atach。image)。有任何想法吗?

enter image description here

谢谢!

回答

4

您需要将窗口设置为不透明并在图形上使用复合。此外,在您的代码中,您只打印一个边框,而不是四个边框,这就是为什么您只能看到一个边框的原因。像这样的东西应该这样做(尽管它会更好地作画基础上,插图的边界,而不是你的RADIUS常数):

import java.awt.AlphaComposite; 
import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Insets; 
import java.awt.RenderingHints; 
import java.io.UnsupportedEncodingException; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.border.AbstractBorder; 

import com.sun.awt.AWTUtilities; 

public class Main { 

    private static class ShadowBorder extends AbstractBorder { 

     private static final int RADIUS = 30; 

     @Override 
     public boolean isBorderOpaque() { 
      return false; 
     } 

     @Override 
     public Insets getBorderInsets(Component c) { 
      return new Insets(RADIUS, RADIUS, RADIUS, RADIUS); 
     } 

     @Override 
     public Insets getBorderInsets(Component c, Insets insets) { 
      insets.top = RADIUS; 
      insets.left = RADIUS; 
      insets.bottom = RADIUS; 
      insets.right = RADIUS; 
      return insets; 
     } 

     @Override 
     public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { 
      Graphics2D g2d = (Graphics2D) g.create(); 
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
      g2d.setColor(new Color(66, 0, 0)); 
      g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, 0.5f)); 
      g2d.fillRect(0, 0, width - RADIUS, RADIUS); 
      g2d.fillRect(width - RADIUS, 0, RADIUS, height - RADIUS); 
      g2d.fillRect(0, RADIUS, RADIUS, height - RADIUS); 
      g2d.fillRect(RADIUS, height - RADIUS, width - RADIUS, RADIUS); 
     } 
    } 

    public static void main(String[] args) throws UnsupportedEncodingException { 
     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setUndecorated(true); 
     AWTUtilities.setWindowOpaque(frame, false); 
     JPanel panel = new JPanel(new BorderLayout()); 
     JButton button = new JButton("Hello"); 
     panel.add(button); 
     panel.setBorder(new ShadowBorder()); 
     frame.setContentPane(panel); 
     frame.setSize(300, 200); 
     frame.setVisible(true); 
    } 
} 
+0

明白了,非常感谢! –

+0

我已经尝试过使用JRE 7这种方法,它不起作用(边框有一些灰色背景)。在JRE 6中,它工作正常,但我需要在JRE 7上运行它。 –

5

要使JFrame的使用,你必须首先改变帧的不透明度定制的透明边框:

frame.setUndecorated (true); 
AWTUtilities.setWindowOpaque (frame, false); 

之后,你的框架不会有任何系统的边框和背景可言,所以你可以画一些透明的(对于例如边界)。顺便说一下,你改变边界的组件必须是非透明的,以及组件下方的容器,以使框架后面的像素“通过”。

您也可以使整个框架半透明的,有些情况是:

AWTUtilities.setWindowOpacity (frame, 0.5f); 

这将使50%透明(和它的作品,即使系统窗口装饰)。

尽管这些功能仅在Win和Mac OS系统上得到了正确支持。

+0

这使得整个边框透明,而不仅仅是边界。 –

+1

我已经说过 - “你可以让***整个框架半透明”。我刚才提到了这种方法,因为它在某些情况下可能对问题作者有用,并且与窗口透明度的整个概念类似。 –