Undecorated JFrame shadow - java

How do you add a shadow to a undecorated jframe?
From what I found online, you might be able to add the jframe to another black translucent window to give a shadow effect.
Or somehow apply something like this to a JFrame:
Border loweredBorder = new EtchedBorder(EtchedBorder.LOWERED);
setBorder(loweredBorder);
Either way I just want to know the best method or maybe a completely different way of getting the same effect like extending from another class and not jframe.
I'm new to Java so I might be going down the wrong direction so any advice is appreciated.

Basically, you need to make a series of layers.
JFrame
ShadowPanel
and content...
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;
import javax.swing.border.EmptyBorder;
public class ShadowWindow {
public static void main(String[] args) {
new ShadowWindow();
}
public ShadowWindow() {
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.setContentPane(new ShadowPane());
JPanel panel = new JPanel(new GridBagLayout());
panel.add(new JLabel("Look ma, no hands"));
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ShadowPane extends JPanel {
public ShadowPane() {
setLayout(new BorderLayout());
setOpaque(false);
setBackground(Color.BLACK);
setBorder(new EmptyBorder(0, 0, 10, 10));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
g2d.fillRect(10, 10, getWidth(), getHeight());
g2d.dispose();
}
}
}

MadProgammer,
frame.setBackground(new Color(0, 0, 0, 0));
is useless if you don't use also:
frame.setOpacity(1.0f);
Setting the default close operation to EXIT_ON_CLSE is bad, the app should close naturely with the end of both processes, so DISPOSE_ON_CLOSE is the right way, reserving the other one to "fix" bugs.
frame.setContentPane(new ShadowPanel());
is useless if you use also (and after):
frame.add(panel);
ShadowPanel's constructor should start with:
super(new GridBagLayout());
instead of:
setLayout(new GridBagLayout());
Additionnally, using a GridBagLayout to only add a single component is a bit disproportionned, isn't it ? What about a GridLayout(1, 1) or even a lazy BorderLayout ?
Return a new Dimension on each call on the preferred size (many of them are done by the machine, during a lot of operation, like repainting, etc) is very expensive. You should return a variable defined in the constructor or the class.
Why override getPreferredSize(), but not getBackground(), nor isOpaque() ?
GraphicsD should be placed inside a try block to dispose of it inside a finally block.

Related

setUndecorated() code is not working correctly

The program works fine, but when I add the setUndecorated code, the panel does not appear. Problem is solving when I minimize and reopen the program. I tried repaint() , but It's not working.
package testing;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class test extends JFrame{
static int width = 900;
static int height = 520;
JFrame frame;
JPanel panel;
JButton selectKey = new JButton("Select KeyIMG");
static BufferedImage bg;
class MyCanvas extends JComponent{
public void paint(Graphics g) {
try {
bg = ImageIO.read(new File("BGFILE"));
} catch (IOException e) {
e.printStackTrace();
}
g.setClip(0, 0, width, height);
g.drawImage(bg,0,0,width,height, this);
g.dispose();panel.repaint();
}
}
public test(){
super("Test");
setBounds(250, 100, width, height);
selectKey.setBounds(width/9,height/2,width/45*8,height/13);
getContentPane().add(new MyCanvas());setUndecorated(true);setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setBackground( new Color(0, 0, 0, 0));
panel.setLayout(null);
panel.add(selectKey);
add(panel);
}
public static void main(String...Args){
new test();
}
}
What's wrong ?
Issues
Overriding paint. It's highly discouraged to override paint, painting is a complex series of compounding methods which work together to produce a the final result. It's highly recommended that you override paintComponent instead
Not calling super.paint, see the previous comment. Unless you know exactly what you're doing and are prepared to take over the responsibility of the paint method, call it's super method, there only a very few use cases I'd consider it safe not to do this.
Using a alpha based color on an opaque component; panel.setBackground(new Color(0, 0, 0, 0));. This is bad idea. Swing only knows how to deal with opaque and transparent components, it doesn't know how it should paint components with alpha based colors. The API will simply ignore any components beneath it, which is likely one of the major causes of your problem
g.dispose(); don't ever dispose of a Graphics context you did not create or copy. Doing so can prevent other components from been painted
Don't call panel.repaint(); from within any paint method, painting paints the current state, it should never do anything to change it, doing so well put you into a spiral of CPU death as it begins to chew up all the CPU cycles, in fact, MyCanvas has no right to be modifying panel anyway and the way your code is set up, it could generate a NullPointerException
"Other" concerns
static BufferedImage bg; is worrisome. No body else has any need to deal with this variable, the only class which should be dealing with it is the MyCanvas class
g.setClip(0, 0, width, height); is pointless (and potentially dangerous), this has already been done before the paint method was called. This is made worse by the fact that you are not relying on the components actual size, which could cause the painting to overrun the visible bounds of the component
Extending from JFrame. You should avoid extending from top level containers, they are complex components to which you rarely add any new/reusable functionality to and they lock you into a single use case, much better to start with a JPanel and add that to whatever container you need
An example...
import java.awt.BorderLayout;
import java.awt.Dimension;
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 javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
class Background extends JComponent {
private BufferedImage bg;
public Background() {
try {
bg = ImageIO.read(new File("/path/to/your/image"));
} catch (IOException e) {
e.printStackTrace();
}
setLayout(new BorderLayout());
}
#Override
public Dimension getPreferredSize() {
return bg == null ? super.getPreferredSize() : new Dimension(bg.getWidth(), bg.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (bg != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(bg, 0, 0, getWidth(), getHeight(), this);
g2d.dispose();
}
}
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.setContentPane(new Background());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
panel.add(new JLabel("This is a label, don't I look pretty"), gbc);
JButton selectKey = new JButton("Select KeyIMG");
panel.add(selectKey, gbc);
panel.setOpaque(false);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static void main(String... Args) {
new Test();
}
}

java - Put JComponent in front of graphics in NullLayoutManager?

I have a JButton in a JPanel that has graphics, but the button won't show as it is in the layer BELOW the graphics.
I've already read this : Put JLabel in front of Graphics 2D Rectangle in JPanel
But the answers tell me not to use the NullLayoutManager.
Is there any way to do it with the NullLayoutManager, because I need to specifically position my JButton in my JPanel?
If this is not possible, are there any other ways I can position a JComponent at a position x, y? I've also googled that and NullLayoutManager is what the world wide web gives me.
Code:
JPanel p = new JPanel(){
#Override
public void paintComponent(Graphics gr){
Graphics2D g = (Graphics2D) gr;
g.setColor(Color.BLACK);
g.fillRect(0, 0, 800, 800);
g.setFont(titlefont);
g.setColor(Color.WHITE);
g.drawString("dont steal my game idea plz", 25, 100);
g.drawImage(bi, 138, 70, null);
repaint();
}
};
p.setLayout(null);
JButton b = new JButton("PLAY");
b.setLocation(100, 200);
b.setFont(ufont);
f.add(p);
p.add(b);
Is there any way to do it with the NullLayoutManager, because I need to specifically position my JButton in my JPanel?
The answer is "yes", but do you understand what the layout managers actually do? How they work and the role they fill in order to replace them and take over the requirements of their functionality?
null layouts are just a bad idea, there are so many things that can wrong with them it's mind numbing just trying to think about it. If none of the stock layout managers do what you want, maybe consider using MigLayout or some other layout manager, possibly even writing your own, at least this way, you will still be able to work within the API, which has been designed to work around layout managers.
There are a couple of other issues, first, you're painting your image AFTER the paint the text, this could cause some issues if the two overlap. Second, you're breaking the paint chain by not calling super.paintComponent, this could result in some unexpected and unwanted results. Third, you don't need to fill the component, use setBackground and let the super.paintComponent deal with it.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
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 DownWithNullLayouts {
public static void main(String[] args) {
new DownWithNullLayouts();
}
public DownWithNullLayouts() {
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 Font titlefont;
private BufferedImage bi;
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(30, 0, 0, 0);
add(new JButton("Play"), gbc);
try {
bi = ImageIO.read(...);
} catch (IOException ex) {
ex.printStackTrace();
}
titlefont = UIManager.getFont("Label.font");
setBackground(Color.BLACK);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - bi.getWidth()) / 2;
int y = (getHeight()- bi.getHeight()) / 2;
g2d.drawImage(bi, x, y, this);
g2d.setFont(titlefont);
g2d.setColor(Color.WHITE);
g2d.drawString("dont steal my game idea plz", 25, 100);
g2d.dispose();
}
}
}
Take a closer look at Painting in AWT and Swing and Performing Custom Painting for more details

load image to JPanel not working

For two days I was trying to load an image into JPanel from a file. I couldn't!
I used JLabel and Icon and it's loaded okay, but I need to load the image to a JPanel directly, is that impossible?
Because almost I saw many and many related problems like this and many people recommended the person who asks the question to load the image into a label!
this is the code :
public class ReadingImage extends JPanel {
JPanel panel;
JFrame frame;
JPanel secPanel;
private BufferedImage img;
public ReadingImage(String path){
frame = new JFrame();
frame.setVisible(true);
frame.setLocation(300, 300);
frame.setSize(300, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
secPanel = new JPanel();
secPanel.setVisible(true);
//secPanel.setLayout(new FlowLayout());
secPanel.repaint();
frame.getContentPane().add(secPanel);
try{
FileImageInputStream fi = new FileImageInputStream(new File(path));
//System.out.println(path);
img = ImageIO.read(fi);
this.repaint();
}
catch (IOException io ){ io.printStackTrace();}
}
#Override
protected void paintComponent(Graphics g){
super.paintComponents(g);
if (img!=null){
g.drawImage(img, 0, 0, this);
repaint();
}
}
}
It's not throwing any exception, but it's not displaying the image in the JPanel!
I adjusted the code many and many times..
any help in this :)
thanks,
Classic confusion caused by extending JPanel and using another JPanel. Replace frame.getContentPane().add(secPanel) with frame.add(this , BORDERLAYOUT.CENTER) and everything should work fine.
You are calling super.paintComponents(g); in paintComponent, not the s at the end, this is going to cause a StackOverflowException eventually, but don't actually ever add the ReadingImage JPanel to anything, so it's never actually painted
This means that there doesn't seem to be any point any point to the secPane
You should also avoid creating frames from within other components, especially from within the constructor, it provides a very limit use case for the component
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageInputStream;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ReadingImage extends JPanel {
private BufferedImage img;
public ReadingImage(String path) {
try {
FileImageInputStream fi = new FileImageInputStream(new File(path));
img = ImageIO.read(fi);
this.repaint();
} catch (IOException io) {
io.printStackTrace();
}
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
g.drawImage(img, 0, 0, this);
repaint();
}
}
public static void main(String[] args) {
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();
frame.add(new ReadingImage("Your image"));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(300, 300);
frame.setSize(300, 500);
frame.setVisible(true);
}
});
}
}
I'm not sure exactly what you are trying to achieve, but I would also encourage you to override the ReadingImage's getPreferredSize method and return the size of the image, this makes it easier to layout
first load the image in Image Icon, lets say the object as 'pic'.
panel1.add(new JLabel(pic));
add and set panel1 to visible.

java custom shaped frame using image [duplicate]

This question already has answers here:
Image/Graphic into a Shape
(3 answers)
Closed 8 years ago.
i like to create a java jframe look like this image.i have already crated jframes with different shapes like triangles ,circles ,polygons and some crazy shapes .but the problem it's too hard[99% impossible ] to create shape like this image.so how can i make a jframe like this.i used this code for create shaped window..
setUndecorated(true);
Polygon polygon = new Polygon();
polygon.addPoint(0, 0);
polygon.addPoint(100,100);
GeneralPath path = new GeneralPath();
path.append(polygon, true);
setShape(path);
now can i convert this image to a shape .then set setshapes.any idea?
or is there anyway to make jframe's fully transperent and jlable which hold image completely visible?
To make a transparent window, you need to set the frames background color's alpha to 0. This is probably the most counter intuitive call I've seen in a while, as if you do this to any other Swing component, you will completely screw up the paint process.
You don't want to change the opacity of the window, as it effectives the entire window and it's contents equally.
For example...
JWindow frame = new JWindow();
frame.setBackground(new Color(0, 0, 0, 0));
You don't have to use a JWindow, but this means I don't need to undecorate it myself...
You also need to make sure that whatever content you add to the window is transparent (opaque = false), so that it doesn't "hide" what's underneath it...
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.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class LeafWindow {
public static void main(String[] args) {
new LeafWindow();
}
public LeafWindow() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JWindow frame = new JWindow();
frame.setBackground(new Color(0, 0, 0, 0));
frame.setContentPane(new LeafPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setAlwaysOnTop(true);
}
});
}
public class LeafPane extends JPanel {
private BufferedImage leaf;
public LeafPane() {
setBorder(new CompoundBorder(
new LineBorder(Color.RED),
new EmptyBorder(0, 0, 250, 0)));
try {
leaf = ImageIO.read(getClass().getResource("/Leaf.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
setOpaque(false);
setLayout(new GridBagLayout());
JButton button = new JButton("Close");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
add(button);
}
#Override
public Dimension getPreferredSize() {
return leaf == null ? new Dimension(200, 200) : new Dimension(leaf.getWidth(), leaf.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (leaf != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(leaf, 0, 0, this);
g2d.dispose();
}
}
}
}
This example deliberate adds a line border to the content as you can see what the original window bounds would be. It also uses a EmptyBorder to force the JButton onto the graphics, but this is just an example...
You'll have to create a shape based on your image. There are different threads here on SO that provide some way how to do this. The best one (based on the description, I didn't try it myself) might be Java - Create a shape from border around image. Another option for more complex images could be Image/Graphic into a Shape.
Another solution might be to use an undecorated frame along with "per-pixel transparency", as explained by Oracle here: http://docs.oracle.com/javase/tutorial/uiswing/misc/trans_shaped_windows.html

JLabel text gets overwritten on transparent bg

Im a newbie to java, Im trying to create an application like a desktop widget for which i have made the JPanel transparent. I have two JLabels on top of it one for holding an image and other for displaying time. I had a timer to update the time displayed in the JLabel. But With a transparent JPanel behind the jlabel's text gets overwritten instead of replacement. After Googling and Looking up on stackoverflow i tried many methods to override the paintcomponent method of the JLabel. But it didnt affect anything. Later I manually called the paintcomponent method inside the timer which worked out. But I feel its just a workaround. I need to know why the paintcomponent didnt get invoked and when it usually gets invoked.
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.RepaintManager;
import javax.swing.SwingConstants;
import javax.swing.text.SimpleAttributeSet;
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class WindowSample {
private JFrame frame;
MyLabel panel1;
// JLabel panel1;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
WindowSample window = new WindowSample();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public WindowSample() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setSize(dim);
frame.setBounds(0, 0, 500, 500);
frame.setBackground(new Color(0, 255, 0, 0));
frame.setUndecorated(true);
frame.setContentPane(new ContentPane());
frame.getContentPane().setBackground(Color.WHITE);
frame.getContentPane().setLayout(null);
// ImagePanel panel = new ImagePanel();
JLabel panel = new JLabel(
scale(new ImageIcon("Science Drops.png").getImage()));
panel.setBounds(0, 0, 200, 200);
panel1 = new MyLabel();
// panel1 = new JLabel();
panel1.setHorizontalAlignment(SwingConstants.CENTER);
panel1.setAlignmentX(SwingConstants.CENTER);
panel1.setFont(new Font("Calibiri",Font.BOLD,16));
panel1.setBounds(0, 205, 200, 50);
Timer n = new Timer();
panel1.setBackground(Color.white);
n.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
// this manual call to paintComponent did the trick. If i remove this line the text gets overwritten over itself for every second.
panel1.paintComponents(panel1.getGraphics());
panel1.setText(df.format(new Date()));
}
}, 1000, 1000);
frame.getContentPane().add(panel1);
frame.getContentPane().add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
#SuppressWarnings("serial")
public class MyLabel extends JLabel {
MyLabel() {
setOpaque(false);
}
#Override
public void paintComponents(Graphics arg0) {
Graphics2D g2d = (Graphics2D) arg0.create();
g2d.clearRect(0, 0, getWidth(), getHeight());
g2d.dispose();
super.paintComponents(arg0);
}
}
public class ContentPane extends JPanel {
public ContentPane() {
setOpaque(false);
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.0f));
g2d.setColor(getBackground());
g2d.fill(getBounds());
g2d.dispose();
super.paintComponent(g);
}
}
public ImageIcon scale(Image src) {
int w = 200;
int h = 200;
int type = BufferedImage.TYPE_INT_ARGB;
BufferedImage dst = new BufferedImage(w, h, type);
Graphics2D g2 = dst.createGraphics();
g2.drawImage(src, 0, 0, w, h, frame);
g2.dispose();
return new ImageIcon(dst);
}
}
Read Backgrounds With Transparency for information on how transparency works and for some possible solutions.
Also, some other comments with your code:
Don't use a null layout. Swing was designed to be used with layout managers for to many reasons to list here.
Custom painting is done by overriding paintComponent() (no "s"). However, in your case I don't see any reason to do custom painting if you follow the advice in the link I provided above. I also don't think you need to do custom painting in your panel, but I don't totally understand what you are attempting to do.
Use javax.swing.Timer instead of java.util.Timer. Have a look at this tutorial from oracle about timers and swing.
You seem to be going about it the hard way...
labels are transparent by default.
labels support icons out of the box (include animated gifs ;))
null layouts are never a good idea, they might seem like a good idea, but you will spend more time correcting for funny little inconsistencies which be resolved using an appropriate layout manager...
java.util.Timer is not a suitable timer for Swing, instead you want to use javax.swing.Timer instead. It will trigger it's updates within the context of the EDT.
Based off what I think you want to do...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MyClock {
public static void main(String[] args) {
new MyClock();
}
public MyClock() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
final JLabel label = new JLabel(df.format(new Date()));
label.setIcon(new ImageIcon("Clock.png"));
Timer timer = new Timer(500, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
label.setText(df.format(new Date()));
}
});
timer.start();
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.setUndecorated(true);
frame.setBackground(new Color(0, 255, 0, 0));
frame.add(label);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Take a look at How to use icons for more details about icon support in Swing.
You may also find Window#alwaysOnTop useful (remember, all frames lead to Window)
I can't believe there is still nobody who answered the right answer. Here's how you get away with this kind of problem :
Apply setOpaque(false) to your components, but also to all the parents.
It will prevent painting problems on your components with transparent backgrounds.

Categories

Resources