Java Swing: Transparent PNG permanently captures original background - java

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

Related

What can cause a Swing application to inconsistently throw null pointer exceptions?

I have a two class project, one class reads one file, and checks each entry in said file against a website, and posts the return data in another file.
If the return data says true(for example), the data point in the file is flashed on the screen. This functionality works.
I invoke this through the following if statement within a while loop.
if (!query.text().contains("unavailable") && !query.text().contains("at least 3 characters long to acquire.") && line != null) {
HitBox h = new HitBox(line); //GUI Class.
fos.write(query.text().getBytes());
fos.write("\n".getBytes());
fos.flush();
}
Below is my GUI class.
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
public class HitBox {
private Timer t;
JWindow frame = new JWindow();
public HitBox(String s) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
frame.setAlwaysOnTop(true);
t = new Timer(1000 * 5, new ActionListener() {
public void actionPerformed(ActionEvent e2) {
SwingUtilities.getWindowAncestor(frame.getComponent(0))
.dispose();
}
});
}
});
frame.setBackground(new Color(0, 0, 0, 0));
TranslucentPane tp = new TranslucentPane(s);
frame.setContentPane(tp);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
t.start();
}
}
class TranslucentPane extends JPanel {
public TranslucentPane(String s) {
add(new JLabel(s));
setOpaque(false);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(0.85f));
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
}
}
This happens using the same set of input data, even if I override the web query, and just return a set value, # a random point in runtime, a JWindow will appear, a nullpointer will be thrown (# my call of the start method of my timer object).
This leads me to believe I'm implementing the timer incorrectly; I'm intrigued by how with consistent data, and return, there is variation in the point it throws the nullpointer.
Exception in thread "main" java.lang.NullPointerException
at HitBox.<init>(HitBox.java:51)
at OriginalGangster.main(OriginalGangster.java:38)
You're not starting your GUI on the GUI thread. You need to move it into the Runnable and be sure to start the Timer after it has been constructed.
e.g.,
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.Timer;
import javax.swing.UIManager;
public class TestHitBox {
public static void main(String[] args) {
String text = "Hello world! This is Hovercraft!";
int seconds = 5;
float composite = 0.85f;
float points = 48f;
HitBox.showMessage(text, seconds, composite, points);
}
}
class HitBox {
public static void showMessage(final String text, final int seconds, final float composite, final float points) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager
.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
final JWindow frame = new JWindow();
frame.setBackground(new Color(0, 0, 0, 0));
TranslucentPane tp = new TranslucentPane(text, composite, points);
frame.setContentPane(tp);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setAlwaysOnTop(true);
new Timer(1000 * seconds, new TimerListener(frame)).start();
}
});
}
}
class TimerListener implements ActionListener {
private JWindow frame;
public TimerListener(JWindow frame) {
this.frame = frame;
}
#Override
public void actionPerformed(ActionEvent e) {
frame.dispose();
((Timer) e.getSource()).stop();
}
}
#SuppressWarnings("serial")
class TranslucentPane extends JPanel {
private float composite;
public TranslucentPane(String s, float composite, float points) {
this.composite = composite;
JLabel label = new JLabel(s);
label.setFont(label.getFont().deriveFont(Font.BOLD, points));
add(label);
setOpaque(false); // this breaks a rule
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(composite));
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose(); // dispose of any graphics we create
}
}
Code updated.
The main code has been moved to a public static method, since this appears to be code to display a message to the user and not to share state with any other code, similar to a JOptionPane message, so I'm making it behave like a JOptionPane.
Timer's ActionListener moved out of constructor for cleanliness.
Added parameters for alpha composite, display time, and message font point size.

Java custom button paintComponent does not repaint the default button background

I am making a custom button in with Swing in Java.
This is how my buttons look like:
I want a lightgray button with rounded corners, I want to add a little image later.
The problem is when I override paintComponent(), the gray rounded will be drawn, but you see the old blue Swing background after it.
The corners of the button must be transparent.
This is my code
package game;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JButton;
public class ItemButton extends JButton {
public ItemButton(String text) {
super(text);
this.setBorderPainted(false);
this.setBorder(null);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(new Color(220, 220, 220));
g2.fillRoundRect(0, 0, this.getWidth() - 10, this.getHeight() - 10, 10, 10);
}
}
I'm not sure why you want to do this this way, as JButton allows you to supply an Icon image, but anyway...
There is a way to do this using JButton, but it's not the right thing to do, instead, you should start by using an AbstractButton as it has no UI delegate painting to it to begin with, 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.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractButton;
import javax.swing.DefaultButtonModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class CustomButton {
public static void main(String[] args) {
new CustomButton();
}
public CustomButton() {
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.setLayout(new GridBagLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends AbstractButton {
public TestPane() {
setModel(new DefaultButtonModel());
MouseHandler mh = new MouseHandler();
addMouseListener(mh);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(40, 20);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics g2d = (Graphics2D) g.create();
g2d.setColor(new Color(220, 220, 220));
g2d.fillRoundRect(0, 0, this.getWidth() - 1, this.getHeight() - 1, 10, 10);
if (getModel().isRollover()) {
g2d.setColor(new Color(128, 128, 128));
g2d.drawRoundRect(0, 0, this.getWidth() - 1, this.getHeight() - 1, 10, 10);
}
g2d.dispose();
}
public class MouseHandler extends MouseAdapter {
#Override
public void mouseEntered(MouseEvent e) {
getModel().setRollover(true);
}
#Override
public void mouseExited(MouseEvent e) {
getModel().setRollover(false);
}
#Override
public void mousePressed(MouseEvent e) {
getModel().setArmed(true);
getModel().setPressed(true);
}
#Override
public void mouseReleased(MouseEvent e) {
getModel().setPressed(false);
getModel().setArmed(false);
}
}
}
}
there are two ways
override getPrefferedSize inside class ItemButton
use proper LayoutManager, I'd be start with GridLayout

Rectangle is not drawn on top

I have a class "Map" which extends JPanel. I add it to a class that extends a JFrame.
public void paintComponent(Graphics g) {
super.paintComponent(g);
int width = Math.abs(startX - endX);
int height= Math.abs(startY - endY);
g.setColor(Color.RED);
g.fillRect(startX, startY, width, height);
}
My class "Map" also contains a label with an image in it. If the image is smalled than the window, when I draw a rectangle it is seen.
In short, it is under the label.
paintComponent is the "bottom" of the paint chain, so anything painted here will appear below everything else.
A better solution might be to add the Map panel to the label (setting the JLabel's layout manager appropriately).
Or, create a "base" panel, set it's layout manager to use a OverlayLayout manager and add the JLabel and Map panel to it.
This will, of course, all depend on what it is you want to achieve...
Updated with "Panel on Label" example
Basically, this takes a JLabel, sets an icon (as the background image), set it's layout as BorderLayout and then adds a JPanel on to it.
Remember, JPanel is opaque by default, so you need to make it transparent ;)
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.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class OverlayLabel {
public static void main(String[] args) {
new OverlayLabel();
}
public OverlayLabel() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JLabel background = new JLabel(new ImageIcon(ImageIO.read(new File("/path/to/image"))));
background.setLayout(new BorderLayout());
background.add(new TestPane());
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(background);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setOpaque(false);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics g2d = (Graphics2D) g.create();
int x = (getWidth() - 20) / 2;
int y = (getHeight() - 20) / 2;
g2d.setColor(Color.RED);
g2d.fillRect(x, y, 20, 20);
g2d.dispose();
}
}
}
Updated with example of OverlayLayout
OverlayLayout basically uses the components x/y alignment to make determinations about how best it should place the individual components
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.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.LineBorder;
public class OverlayLabel {
public static void main(String[] args) {
new OverlayLabel();
}
public OverlayLabel() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JLabel background = new JLabel(new ImageIcon(ImageIO.read(new File("/path/to/image"))));
background.setAlignmentX(0.5f);
background.setAlignmentY(0.5f);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new OverlayLayout(frame.getContentPane()));
frame.add(new TestPane());
frame.add(background);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setOpaque(false);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics g2d = (Graphics2D) g.create();
int x = (getWidth() - 20) / 2;
int y = (getHeight() - 20) / 2;
g2d.setColor(Color.RED);
g2d.fillRect(x, y, 20, 20);
g2d.dispose();
}
}
}
And finally, if none of that is working for you, you could use JLayeredPane as the base, which will allow you to determine the z-order of each component...
See How to use layered panes for more details...

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...

I need to set a background image for a java DesktopApplication

I didn't know how, and there is no background image property. I researched the answer but all I could find was to set a labels icon inside a panel with a null layout. This worked and my image is there, but it is covering all but a single text field. Can I change the Z value of this label? I do not see a 'move to back' option, if there is one.
This should solve your problem:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class TestImage {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
ContentPane panel = new ContentPane();
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setVisible(true);
}
});
}
private static class ContentPane extends JPanel {
BufferedImage image = null;
public ContentPane() {
try {
String pathToImage = "C:/Users/Branislav/Pictures/sun.jpg";
image = ImageIO.read(new File(pathToImage));
} catch (IOException e) {
e.printStackTrace();
}
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
};
#Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(), image.getHeight());
}
}
}
Basically, I set image on JPanel (ContentPane). Also, size of your JPanel depends on size of image (at least in this case).
Regards.

Categories