Alpha from PNG and Swing frame border

Hello.



I’m trying to display a frame (window) with custom border.

I can skin border with no problem, but alpha from ma PNG is not enable on the render.



the goal is to be able to display a frame with border like this:





Border have transparency for having a custom shape.



Any idea ?

to achieve a transparency for a swing-component, based on .png images, you have to overwrite the paintComponent() method. @see BackgroundPanel



On borders the method is called paintBorder(). @see MyBorder

So i suggest writing your own borderclass with the overwritten paintBorder().



But the total windowtranparency is fake!!

A JWindow is a hevyweight container, so its appearence is mostly controlled by the operating system. Afaik its not intended to make a windows background transparent.

But to fake this just use a screencapture of the current desktop, and use the area of the captured image,  where the window should be drawn, as backgroundimage of the backgroundpanel.



I googled a bit and composed this solution:


package com.pass.vb3d.quickwin.test;

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.awt.image.ImageObserver;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.border.AbstractBorder;

public class TransparentWindow extends JWindow {

   public static void main(String[] argv) {
      new TransparentWindow().show();
   }

   public TransparentWindow() {

      setSize(400, 400);
      centerOnScreen(this);
      // capture background before we add components;
      // we need JWindows's size here and component's location must also have
      // been done!
      BackgroundPanel backgroundPanel = new BackgroundPanel(this);

      URL url = TestTransparentSwingBorder.class.getClass().getResource(
            "/com/pass/vb3d/quickwin/data/bla.png");

      ImageIcon image = new ImageIcon(url);
      image = new ImageIcon(image.getImage().getScaledInstance(400, 400,
            Image.SCALE_FAST));
      backgroundPanel.setBorder(new MyBorder(image));

      JButton closeButton = new JButton("Close");
      closeButton.setSize(100, 100);
      closeButton.setLocation(backgroundPanel.getWidth() / 2
            - closeButton.getPreferredSize().width / 2, backgroundPanel
            .getHeight()
            / 2 - closeButton.getPreferredSize().height / 2);
      closeButton.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            TransparentWindow.this.setVisible(false);
            TransparentWindow.this.dispose();
            System.exit(0);
         }
      });
      backgroundPanel.add(closeButton);

      getContentPane().add(backgroundPanel);
   }

   private void centerOnScreen(Container c) {
      Dimension paneSize = c.getSize();
      Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
      c.setLocation((screenSize.width - paneSize.width) / 2,
            (screenSize.height - paneSize.height) / 2);
   }
}

class BackgroundPanel extends JPanel {

   BufferedImage image = null;

   BackgroundPanel(JWindow window) {
      Rectangle rect = window.getBounds();
      try {
         image = new Robot().createScreenCapture(rect);
      } catch (AWTException e) {
         throw new RuntimeException(e.getMessage());
      }
   }

   protected void paintComponent(Graphics g) {
      g.drawImage(image, 0, 0, this);
   }
}

class MyBorder extends AbstractBorder implements ImageObserver {

   private ImageIcon image;
   private int thickness;
   private boolean rounded = false;

   public MyBorder(ImageIcon img) {
      image = img;
   }

   @Override
   public void paintBorder(Component c, Graphics g, int x, int y, int width,
         int height) {
      super.paintBorder(c, g, x, y, width, height);

      g.drawImage(image.getImage(), x, y, this);

   }

   @Override
   public boolean imageUpdate(Image img, int infoflags, int x, int y,
         int width, int height) {
      // TODO Auto-generated method stub
      return false;
   }

}