2012-05-04 24 views
14

Translucent JFrame sınırı (see here) hakkında soru soruyordum ve çok iyi cevaplar aldım, ancak maalesef cevaplar sadece JDK 6'da mükemmel bir şekilde çalışıyor, ancak 7 değil. Herhangi bir fikir nasıl çalışır? JDK 7 mi?Translucent JFrame sınır JDK 7

import java.awt.*; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 
import javax.swing.border.AbstractBorder; 


public class ShadowBorder extends AbstractBorder { 

private static final int RADIUS = 30; 
private static BufferedImage shadowTop; 
private static BufferedImage shadowRight; 
private static BufferedImage shadowBottom; 
private static BufferedImage shadowLeft; 
private static BufferedImage shadowTopLeft; 
private static BufferedImage shadowTopRight; 
private static BufferedImage shadowBottomLeft; 
private static BufferedImage shadowBottomRight; 
private static boolean shadowsLoaded = false; 

public ShadowBorder() { 
    if (!shadowsLoaded) { 
     try { 
      shadowTop = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-top.png")); 
      shadowRight = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-right.png")); 
      shadowBottom = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-bottom.png")); 
      shadowLeft = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-left.png")); 

      shadowTopLeft = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-top-left.png")); 
      shadowTopRight = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-top-right.png")); 
      shadowBottomLeft = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-bottom-left.png")); 
      shadowBottomRight = ImageIO.read(getClass().getResource("/cz/vutbr/fit/assets/shadow-bottom-right.png")); 

      shadowsLoaded = true; 
     } catch (IOException ex) { 
      Logger.getLogger(ShadowBorder.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 
} 

@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.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, 1f)); 

    int recWidth = width - (2 * RADIUS); 
    int recHeight = height - (2 * RADIUS); 
    int recX = width - RADIUS; 
    int recY = height - RADIUS; 

    //edges 
    g2d.drawImage(shadowTop.getScaledInstance(recWidth, RADIUS, Image.SCALE_REPLICATE), RADIUS, 0, null); 
    g2d.drawImage(shadowRight.getScaledInstance(RADIUS, recHeight, Image.SCALE_REPLICATE), recX, RADIUS, null); 
    g2d.drawImage(shadowBottom.getScaledInstance(recWidth, RADIUS, Image.SCALE_REPLICATE), RADIUS, recY, null); 
    g2d.drawImage(shadowLeft.getScaledInstance(RADIUS, recHeight, Image.SCALE_REPLICATE), 0, RADIUS, null); 

    //corners 
    g2d.drawImage(shadowTopLeft, 0, 0, null); 
    g2d.drawImage(shadowTopRight, recX, 0, null); 
    g2d.drawImage(shadowBottomLeft, 0, recY, null); 
    g2d.drawImage(shadowBottomRight, recX, recY, null); 

} 
} 

Teşekkür a:

JDK 6 yılında şuna benzer:

enter image description here

Ve JDK 7:

enter image description here

Ve kod şöyle görünür çok!

+1

Hata veritabanını kontrol ettiniz mi? Güzel ekran görüntüleri BTW. +1 –

+0

Google'da bu konuyla ilgili bir şey denendi, ancak başarı yok. –

cevap

3

Sadece sorunumu çözdüm. Sorun şu ki, JDK 7, setBackground() yönteminde JDK6'dan AWTUtilities.setWindowOpaque() yöntemini uygular ve JFrame için varsayılan arka planı farklı bir yerde ayarlayan (NetBeans :-)) idi, bu nedenle new Color(0, 0, 0, 0); için arka plan ayarı, JFrame'i saydamlaştırır ve her şey iyi gider.

2

Bu iş parçacığına tökezleyen ve kendi şeffaf penceresini isteyen kişi için bu örneği hazırladım. Webde ne kadar az bilginin bulunduğu ile neredeyse işe yarayan bir şey bulmak için bir bacağını kırmak zorunda kaldım ve görüntü dosyaları ya da herhangi bir şey kullanmıyordum. (Farklı örneklerde, this sitesinde)

public class GradientTranslucentWindowDemo 
{ 
    public static void main(String[] args) 
    { 
     // Create the GUI on the event-dispatching thread 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       final JFrame f = new JFrame("Per-pixel translucent window"); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

       f.setUndecorated(true); 
       f.setBackground(new Color(0, 0, 0, 0)); 

       final BufferedImage backrgoundImage = makeBackrgoundImage(400, 400); 

       JPanel panel = new JPanel() 
       { 
        @Override 
        public void paintComponent(Graphics g) 
        { 
         super.paintComponent(g); 
         if (g instanceof Graphics2D) 
         { 

          g.drawImage(backrgoundImage, 0, 0, null); 
         } 
        } 
       }; 
       panel.setOpaque(false); 
       f.setContentPane(panel); 

       f.setLayout(new GridBagLayout()); // Centers the button 
       f.add(new JButton(new AbstractAction("Close") 
       { 
        @Override 
        public void actionPerformed(ActionEvent e) 
        { 
         f.dispose(); 
        } 
       })); 

       f.setBounds(100, 100, 400, 400); 
       f.setVisible(true); 
      } 
     }); 
    } 

    static BufferedImage makeBackrgoundImage(int w, int h) 
    { 
     BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 

     // Draw something transparent 
     Graphics2D g = img.createGraphics(); 
     g.setPaint(new RadialGradientPaint(new Point2D.Float(w/2, h/2), (w + h)/4, new float[]{0, 1}, new Color[]{Color.RED, new Color(1f, 0, 0, 0)})); 
     g.fillRect(0, 0, w, h); 
     g.setPaint(Color.RED); 
     g.drawRect(0, 0, w - 1, h - 1); 
     g.dispose(); 

     return img; 
    } 
}