2012-05-04 12 views
14

Stavo facendo una domanda sul bordo JFrame traslucido (see here) e ho ottenuto ottime risposte, ma sfortunatamente, date risposte funzionano perfettamente solo su JDK 6, ma non 7. Qualche idea su come farlo funzionare con JDK 7?Bordo JFrame traslucido JDK 7

In JDK 6 Sembra che questo:

enter image description here

E JDK 7:

enter image description here

E il mio codice simile a questo:

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); 

} 
} 

Grazie a sacco!

+1

Hai controllato il database dei bug? Belle schermate BTW. +1 –

+0

Cercato su Google qualcosa su questo argomento, ma senza successo. –

risposta

3

Ho appena risolto il mio problema. Il problema era che JDK 7 implementava il metodo AWTUtilities.setWindowOpaque() da JDK6 nel metodo setBackground() e io (NetBeans ha fatto :-)) impostando lo sfondo predefinito per JFrame in un posto diverso, quindi l'impostazione di sfondo su new Color(0, 0, 0, 0); rende JFrame trasparente e tutto procede bene ora.

2

Per chi si imbatte in questo filo e vuole la sua finestra trasparente, ho ideato questo esempio. Con quante poche informazioni sono disponibili sul web, ho quasi dovuto rompere una gamba per trovare qualcosa che funziona e non usa file di immagine o altro. (Combinato da diversi esempi sul sito this)

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; 
    } 
} 
Problemi correlati