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