Creating a JFrame you can click through - java

I'm trying to create a jframe that the user can click through. I'm not looking for opacity but transparency.
I need a solution that works on all OS and not just Windows because I can't use
WindowUtils.setWindowTransparent(frame, true);
WindowUtils.setWindowAlpha(frame, 0.6f);
or
AWTUtilities.setWindowOpaque(this, false);
AWTUtilities.setWindowOpacity(this, 0.8f);
Can I accomplish this with java alone? It's ok if there is a library that I must use.
EDIT: I have my jframe undecorated and here is the code for it.
frame = new JDialog();
frame.setUndecorated(true);
frame.setVisible(true);
frame.setOpacity(Shared.opacity);
frame.setLocation(0, 0);
frame.setSize(Shared.screenWidth, Shared.screenHeight);
When I say the user can click through what I mean is that if my frame is on top but they have a window under mine, clicking on mine would bring the one under on top.

A completely transparent window can be achieved in Java 7 by using a completely transparent background color, for example...
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
The problem you will have is, that anywhere there is any kind of solid pixel (even if it is transparent), it will stop the mouse events from going beyond the window...
This means that every child component you add to the frame (that you want to be able to click through) will need to be transparent as well.
I use a similar technique for some of my utility programs and include a MouseListener on the main opaque component to make the window more visible so I can drag it if I want to it, but that's stuff for another question ;)
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ClickThroughWindow {
public static void main(String[] args) {
new ClickThroughWindow();
}
public ClickThroughWindow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.setAlwaysOnTop(true);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setOpaque(false);
setLayout(new GridBagLayout());
add(new JLabel("Hello"));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(getBackground());
// g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
// g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(Color.BLACK);
g2d.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
g2d.dispose();
}
}
}
You can find more details at How to Create Translucent and Shaped Windows, in particular How to Implement Per-Pixel Translucency

Related

Ugly Swing Button Background

I have a GUI, and the main panels have transparent backgrounds, so
one can see the background image through them. The problem is, clicking on a
button on one of this panels, on Mac OS, where buttons have round borders, their backgrounds turn in a not-transparent color. How could I avoid this?
Here an image:
Simply make the button transparent using setOpaque(false). Never use a alpha color for a background color, Swing only deals with opaque or not opaque components, it does not know how to deal with alpha based colors.
If you use an alpha based background color, Swing does not know that 1- it's suppose to prepare the Graphics context correctly before painting the component and 2- that the components below the component will also need to be updated when the component changes.
Using alpha background colors will generate random and annoying paint artifacts as the complexity of the UI increases and the changes begin to occur (the UI is updated)
See Painting in AWT and Swing and Performing Custom Painting for more details
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage background;
public TestPane() {
JButton btn = new JButton("I'm a transparent button");
btn.setOpaque(false);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(btn, gbc);
add(new JButton("I'm not a transparent button"), gbc);
try {
background = ImageIO.read(new File("C:\\hold\\thumbnails\\issue522.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(), background.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - background.getWidth()) / 2;
int y = (getHeight() - background.getHeight()) / 2;
g2d.drawImage(background, x, y, this);
g2d.dispose();
}
}
}
}
If you want to paint an translucent background, you will need to override the components paintComponent method and paint it yourself, making sure that the component is marked as transparent (not opaque) first

custom round skin gui

In looking for a starting place to how to create a round interface. I have tried looking into the docs and tried looking into other plugins for Eclipse. I'm just starting to build gui's with java and everything I find is either asking for me to be a part of a company to use their product or want a few hundred dollars.
I'm just a humble coder trying my hand at gui's and a personal project I'm working on wants a round gui skin.
There are, at least, two ways you might achieve this...
You could...
Use JFrame#setShape to alter the shape of the main window, for example...
JFrame frame = new JFrame("Testing");
frame.getContentPane().setBackground(Color.RED);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(new JLabel("Boo!"));
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setUndecorated(true);
frame.setShape(new Ellipse2D.Double(0, 0, 200, 200));
frame.setVisible(true);
This is simple, but frankly, looks crap. There's no way to implement soft clipping to smooth out the edges with this technique...
You could...
Create a transparent window and "fake" the shape...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class CircleUI {
public static void main(String[] args) {
new CircleUI();
}
public CircleUI() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new CirclePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class CirclePane extends JPanel {
public CirclePane() {
setOpaque(false);
setLayout(new GridBagLayout());
add(new JLabel("Boo!"));
setBackground(Color.RED);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2d.setColor(Color.RED);
g2d.fill(new Ellipse2D.Double(0, 0, getWidth() - 1, getHeight() - 1));
g2d.dispose();
}
}
}
Which, arguably, produces a nicer looking result, but will allow you to display components beyond the shape (allow them to overflow), so you need to be able to manage the content to ensure that this doesn't happen...
You could...
Do both...
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// This is the secret here...
JPanel content = new JPanel(new BorderLayout());
content.setOpaque(false);
content.setBorder(new EmptyBorder(1, 1, 1, 1));
content.add(new CirclePane());
frame.setContentPane(content);
frame.pack();
int width = frame.getWidth();
int height = frame.getHeight();
frame.setShape(new Ellipse2D.Double(0, 0, width, height));
frame.setLocationRelativeTo(null);
frame.setVisible(true);
What this does is uses the setShape method from the first example, with the soft clipping from the second example and combines them. This is done by using another JPanel to act as the container for our "fake" shape panel and supplying a very small (1 pixel) empty border. This pushes the size of the frame out from the edge of our soft clipping panel, but means that any components that overflow it, will be clipped...
Call the setOpacity method on your JFrame. More details here:
http://java-demos.blogspot.com/2012/09/how-to-create-shaped-jframes-in-java.html
Other options for Java 6 and Java 7: click here for examples in another solution
JFrame frame = new JFrame();
frame.setUndecorated(true);
AWTUtilities.setWindowShape(frame, new Ellipse2D.Double(0, 0, 100, 100));
Not to be rude, but you really could have found this if you spent 5 minutes Googling or searching on Stack Overflow...
If you really want to learn Java GUI's, you should spend some time studying AWT, Swing, or JavaFX, the core Java libraries for doing GUI work, and basic objects like JFrame and JWindow, and creating menus, buttons, ActionListeners and layouts.

Fullscreensize & Frame in front of it

I am (still) a beginner in Java, and I created a little software which contains a main frame.
I need to cover all the Desktop behind my software such as a windows 98 installing screen : (I need the black and blue screen behing, covering all the task bar etc).
In order to do this, I used GraphicsDevice which goes full screen. It is exactly what I needed :
public class Fond_noir extends JFrame {
private boolean isFullScreen = false;
private GraphicsDevice device;
public Fond_noir(int etat) {
GraphicsEnvironment env = GraphicsEnvironment
.getLocalGraphicsEnvironment();
this.device = env.getDefaultScreenDevice();
initFullScreen(etat);
}
private void initFullScreen(int etat) {
isFullScreen = device.isFullScreenSupported();
if (etat==0)
{
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
}
if (etat==1)
{
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
}
setUndecorated(isFullScreen);
setResizable(!isFullScreen);
if (isFullScreen) {
// Full-screen mode
device.setFullScreenWindow(this);
validate();
} else {
// Windowed mode
this.setExtendedState(MAXIMIZED_BOTH);
this.setVisible(true);
}
}
}
Then, I call this method in a main somewhere else, (there's no problem with this) :
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Fond_noir(0);
Choix_Langue inst = new Choix_Langue(); // main frame
inst.setLocationRelativeTo(null);
inst.setVisible(true);
} } ); }
But the problem is, that my main frame can't show-up, and it's hidden behind my fullscreen.. I'd like the opposite !
Or when I click on my main frame in my task bar (aften using the window key of my keyboard ofc..) I can only see my main frame, and the fullscreen is not showing-up with the frame
=> Is there a way to show both my frame and my GraphicsDevice ? Using "priorities" between them..?
Thanks for reading !
Use this:
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setUndecorated(true);
frame.setAlwaysOnTop(true)
Undecorated will remove the titlebars. Also instead of trying to show both the frames seperately. Add the small one to the bigger one.
bigFrame.add(smallFrame);
bigFrame.setVisible(true);
Example to show that it works:
I'm not sure you need to go full screen exclusive mode, for example, you can size a border-less frame to fit the default screen size and make it always on top to help it cover all other windows in the system and then simply use a JDialog as the primary interface to work with the user, for example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class FullScreenBackground {
public static void main(String[] args) {
new FullScreenBackground();
}
public FullScreenBackground() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
JFrame frame = new JFrame("Testing");
frame.setAlwaysOnTop(true);
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new BackgroundPane());
frame.setLocation(0, 0);
frame.setSize(dim);
frame.setVisible(true);
JDialog dialog = new JDialog(frame);
dialog.setContentPane(new InstallPane());
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
});
}
public class InstallPane extends JPanel {
public InstallPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(new JLabel("<html><h1>Welcome to my fancy pancy background screen<h1></html>"), gbc);
}
}
public class BackgroundPane extends JPanel {
private BufferedImage bg;
public BackgroundPane() {
}
#Override
public void invalidate() {
super.invalidate();
bg = null;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bg == null) {
bg = new BufferedImage(1, getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bg.createGraphics();
LinearGradientPaint lgp = new LinearGradientPaint(
new Point(0, 0),
new Point(0, getHeight()),
new float[]{0f, 1f},
new Color[]{Color.BLACK, Color.BLUE}
);
g2d.setPaint(lgp);
g2d.fillRect(0, 0, 1, getHeight());
}
g.drawImage(bg, 0, 0, getWidth(), getHeight(), this);
}
}
}
Updated
If changing all the "frames" is not hard, you could consider making the following changes to the above example...
JFrame frame = new JFrame("Testing");
frame.setAlwaysOnTop(true);
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new BackgroundPane());
frame.setLocation(0, 0);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setSize(dim);
// This will stop the background window from become focused,
// potentially hiding the other windows
frame.setFocusableWindowState(false);
frame.setFocusable(false);
frame.setVisible(true);
JFrame dialog = new JFrame();
// Will need to add this to each frame...
dialog.setAlwaysOnTop(true);
dialog.setContentPane(new InstallPane());
dialog.pack();
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
The other problem you might face is the fact that alwaysOnTop is platform dependent, meaning that it might behaviour differently on different platforms.
Changing extends JFrame to extends JDialog really would be a simpler and more stable change...
I found a solution with all your anwers.
Instead of using another frame I used a JWindow for the background :
public class Fond_noir extends JWindow{
Panel panel = new Panel();
public Fond_noir(int etat) {
if (etat==0)
{
setSize(2300,4000);
setLocationRelativeTo(null);
setVisible(true);
}
if (etat==1)
{
dispose();
}
panel.setBackground(Color.black);
add(panel);
}
class Panel extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g);
}
}
}
Then while trying to change the "extends JFrame" of my main frame to "extends JDialog", it made me delete this horrible line in the code : this.setState(Frame.ICONIFIED); !!!!
It explains why I had to look for my icon all the time.. So I kept my JFrame..
So now it opens a background window AND the frame at the same time :)
Thank you everyone ! Next time I won't use that much frames.

Replace JTextField with an Image?

I've been searching on way's to replace a JTextField with an Image & nothing comes up. Is it possible to add a jtextfield onto an image or replace on with an image?
I'm using a JPanel & I am trying to put the JtextField inside the image below:
There are several ways this might be achieved...
The simplest might be to use a JLabel, set it's layout manager to something BorderLayout and simply add the text field to it...
JTextField field = new JTextField();
field.setOpaque(false);
JLabel label = new JLabel();
label.setIcon(...);
label.setLayout(new BorderLayout());
label.add(field);
For example...
This will generate...
If you prefer the text field to be transparent, you could add field.setBackground(new Color(0, 0, 0, 0));, which generates...
And if you don't want the border, add field.setBorder(null);, which generates...
Updated with another example...
Or perhaps you'd prefer a self contained class...
This is a little tricky, because paintComponent not only paints the background, but the text, you need some way to insert the background under the text. To this end, I don't actually call super.paintComponent, but instead, we cheat, and call getUI().paint directly. This ensures that the text of the field is painted, but allows us to paint our own background before it...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class BackgroundTextField {
public static void main(String[] args) {
new BackgroundTextField();
}
public BackgroundTextField() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TextFieldBackground());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TextFieldBackground extends JTextField {
private BufferedImage img;
public TextFieldBackground() {
setColumns(10);
setOpaque(false);
setBorder(new EmptyBorder(2, 2, 2, 2));
setBackground(new Color(0, 0, 0, 0));
try {
img = ImageIO.read(getClass().getResource("/y9yBe.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
}
#Override
public Dimension getPreferredSize() {
return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(img, 0, 0, this);
getUI().paint(g2d, this);
g2d.dispose();
}
}
}
There are limitations to this, the field should never be bigger then the image, as the image is not repeated, but I'm sure you could use a for-loop to stitch a bunch of images together...

Java Swing: Transparent PNG permanently captures original background

I have the following code:
import javax.swing.JWindow;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
public class sutff extends JWindow
{
//Get transparent image that will be use as splash screen image.
Image bi=Toolkit.getDefaultToolkit().getImage("window.png");
ImageIcon ii=new ImageIcon(bi);
public sutff()
{
try
{
setSize(ii.getIconWidth(),ii.getIconHeight());
setLocationRelativeTo(null);
show();
//Thread.sleep(10000);
//dispose();
//JOptionPane.showMessageDialog(null,"This program will exit !!!","<>",JOptionPane.INFORMATION_MESSAGE);
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
//Paint transparent image onto JWindow
public void paint(Graphics g)
{
g.drawImage(bi,0,0,this);
}
public static void main(String[]args)
{
sutff tss=new sutff();
}
}
The purpose is to create a window that is translucent and resembles Windows Aero-style glass. I have the following transparent png that I am using:
http://i.imgur.com/5UNGbsr.png
The problem is that since its transparent, its suppose to show the things behind the window, right? That's what it does when first executed, except whatever window is behind this "transparent window" when it first starts up, the program somehow creates an "image" of that and permanently attaches it with the window. So even if I minimize the windows behind this "transparent window," the image of the first background window remains.
Here is a screenshot:
When I took this screen shot, I had already minimized the command prompt and the IDE which can be seen in the background, yet it still remains in the background of the window.
What am I doing wrong?
Don't override the paint() method of a top level container, especially when you don't invoke super.paint(). This will cause painting problems. If you ever do need to do custom painting then you should override the paintComponent() method of JPanel (or JComponent) and then add the panel to the window/frame. Read the Swing tutorial on Custom Painting. This advice is given daily, I don't know why people still try to override paint()???
However this is only one of your problems. The better solution is to add your image to a JLabel and then add the label to the window. You will also need to make the window background transparent:
import javax.swing.*;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import java.awt.*;
import java.awt.Image;
import java.awt.Toolkit;
public class Stuff extends JWindow
{
//Get transparent image that will be use as splash screen image.
Image bi=Toolkit.getDefaultToolkit().getImage("transparent.png");
ImageIcon ii=new ImageIcon(bi);
public Stuff()
{
try
{
setBackground( new Color(0, 0, 0, 0) );
setSize(ii.getIconWidth(),ii.getIconHeight());
setLocationRelativeTo(null);
JLabel label = new JLabel(ii);
add(label);
show();
//Thread.sleep(10000);
//dispose();
//JOptionPane.showMessageDialog(null,"This program will exit !!!","<>",JOptionPane.INFORMATION_MESSAGE);
}
catch(Exception exception)
{
exception.printStackTrace();
}
}
/*
//Paint transparent image onto JWindow
public void paint(Graphics g)
{
super.paint(g);
g.drawImage(bi,0,0,this);
}
*/
public static void main(String[]args)
{
Stuff tss=new Stuff();
}
}
The problem is, you window is actually transparent. Java still thinks that the Window opaque and therefore won't update the graphics in such away as to show what's actually behind.
Creating a transparent window is relatively simple in Java since Java 1.6.10 (I think)
The following is a very simple example, using a semi transparent paint effect that will allow what ever falls below the window to continue to be painted correctly.
import com.sun.awt.AWTUtilities;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TransaprentBlur {
public static void main(String[] args) {
new TransaprentBlur();
}
public TransaprentBlur() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
// Java 6...
// AWTUtilities.setWindowOpaque(frame, true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setOpaque(false);
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
System.exit(0);
}
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Shape shape = new RoundRectangle2D.Float(0, 0, getWidth() - 1, getHeight() - 1, 20, 20);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(new Color(225, 225, 225, 128));
g2d.fill(shape);
g2d.setColor(Color.GRAY);
g2d.draw(shape);
g2d.dispose();
}
}
}
Update with image example
Screen shoots showing windows been moved behind the window...
Basically, all you need to do, is place you image rendering code with in the paintComponent method of TestPane
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TransaprentBlur {
public static void main(String[] args) {
new TransaprentBlur();
}
public TransaprentBlur() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
// Java 6...
// AWTUtilities.setWindowOpaque(frame, true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage image;
public TestPane() {
try {
image = ImageIO.read(getClass().getResource("/5UNGbsr.png"));
} catch (IOException ex) {
}
setOpaque(false);
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
System.exit(0);
}
}
});
}
#Override
public Dimension getPreferredSize() {
return image == null ? super.getPreferredSize() : new Dimension(image.getWidth(), image.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - image.getWidth()) / 2;
int y = (getHeight() - image.getHeight()) / 2;
g2d.drawImage(image, x, y, this);
g2d.dispose();
}
}
}
}

Categories