What I'm trying to do here is call the repaint() method from within my loadbg() method. However, repaint() isn't working, and my image (stored in the var bg) won't load onto the screen. Any suggestions as to why this won't work?
package core;
/*** #author Adil
* 2DPlatformer
* Written by Adil
* Built upon the player-core framework (written by Adil)
* GNU Licensed
*/
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.ImageIcon;
#SuppressWarnings("serial") //Suppress serial warning ID
public class Core extends JFrame {
public static void main(String[] args) {
DisplayMode dm = new DisplayMode(800, 600, 16,
DisplayMode.REFRESH_RATE_UNKNOWN);
//new display with parameters 800x600 + 16 bit color depth
Core i = new Core(); //new core class var
i.run(dm);
}
//variables for image loading below
public Screen s;
public Image bg;
public boolean loaded = false;
//run method below
public void run(DisplayMode dm) {
setBackground(Color.BLACK);
setForeground(Color.WHITE);
setFont(new Font("Ubuntu", Font.PLAIN, 24));
s = new Screen();
loaded = false;
try {
s.setScreenSize(dm, this);
loadbg();
try {
Thread.sleep(5000);
} catch (Exception ex) {
}
} finally {
s.RestoreScreen();
}
}
public void loadbg() {
bg = new ImageIcon(
"file:\\\\home\\adil\\Desktop\\pack_2\\bgame.jpg").getImage();
loaded = true;
s.repaint();//s is my screen object, but it won't repaint.
}
public void paint(Graphics g) {
if (g instanceof Graphics2D) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
if (loaded) {
g.drawImage(bg, 0, 0, null);
}
}
}
1) better way would be put Icon/ImageIcon to JLabel, rather than paint Image by using paint()
2) for Swing is there paintComponent() instead of paint()
3) don't use Thread.sleep(int) for Swing GUI use javax.swing.Timer instead, because during Thread.sleep(int) you GUI simply freeze, nothing else
Related
I have a JLabel image on a JFrame that I want too brighten upon hovering, have tried a few things however nothing seems to be working, here's my current code:
public class DivinationLogo extends JLabel {
private BufferedImage logo;
public DivinationLogo() {
super();
try {
logo = ImageIO.read(getClass().getResourceAsStream("/assets/images/logo.png"));
} catch (IOException e) {
e.printStackTrace();
}
// setIcon(new ImageIcon(logo));
setIconTextGap(0);
setBorder(null);
setText(null);
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
Functions.openWebPage(Config.website);
}
#Override
public void mouseEntered(MouseEvent e) {
Functions.brightnessControl(logo, .3F);
}
#Override
public void mouseExited(MouseEvent e) {
Functions.brightnessControl(logo, 1.0F);
}
});
setBounds(-5, 1, 247, 106);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(logo, -5, 1, null);
}
}
Functions.brightnessControl:
public static Image brightnessControl(Image image, float brightness) {
BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics bg = bi.getGraphics();
if (bi.getColorModel().hasAlpha()) {
System.out.println("Image has got an alpha channel");
}
bg.drawImage(image, 0, 0, null);
bg.dispose();
RescaleOp rescaleOp = new RescaleOp(brightness, 0, null);
rescaleOp.filter(bi, bi);
image = bi;
return bi;
}
Currently, it does nothing which confuses me. If anyone knows how this is achieved, please feel free too let me know :)
Ok, so the basic idea is, when the mouse enters the component, you want to generate a "bright" version of the component (I know, obvious, but bear with me)
The problem is, you have a Graphics context and you need a image :/
The following is not overly optimised, but without spending a lot of time adding in PropertyChange support, this will give you the basic idea.
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
JFrame frame = new JFrame();
frame.setLayout(new GridBagLayout());
JLabel label = new BrightLabel();
label.setIcon((new ImageIcon(ImageIO.read(Main.class.getResource("background.png")))));
frame.add(label);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class BrightLabel extends JLabel {
private MouseAdapter mouseHandler;
private boolean isHover = false;
#Override
public void addNotify() {
super.addNotify();
mouseHandler = new MouseAdapter() {
#Override
public void mouseEntered(MouseEvent e) {
isHover = true;
repaint();
}
#Override
public void mouseExited(MouseEvent e) {
isHover = false;
repaint();
}
};
System.out.println("...");
addMouseListener(mouseHandler);
}
#Override
public void removeNotify() {
super.removeNotify();
if (mouseHandler != null) {
removeMouseListener(mouseHandler);
}
mouseHandler = null;
}
#Override
protected void paintComponent(Graphics g) {
if (!isHover) {
super.paintComponent(g);
return;
}
BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
super.paintComponent(g2d);
g2d.dispose();
Image bright = brightnessControl(img, 1.3f);
g.drawImage(bright, 0, 0, this);
}
public Image brightnessControl(Image image, float brightness) {
BufferedImage bi = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics bg = bi.getGraphics();
if (bi.getColorModel().hasAlpha()) {
System.out.println("Image has got an alpha channel");
}
bg.drawImage(image, 0, 0, null);
bg.dispose();
RescaleOp rescaleOp = new RescaleOp(brightness, 0, null);
rescaleOp.filter(bi, bi);
image = bi;
return bi;
}
}
}
Essentially, when the mouse enters or exists the component, we set the isHover property. We then call repaint to trigger a new paint pass.
When the component is painted, if isHover is true, we take over the painting process slightly, generating our own buffer and painting the component to it. This gives us our base image. From there we brighten the image and paint it to the Graphics context
Arguments in java are passed by value so your the function you have to brighten the image doesn't have an effect on the image you passed to it.
You're missing the repaint() call after changing the image.
You definitely don't want to prepare the hover image every time you hover over the image. Pre-calculate the hover in the constructor and assign it to a separate image.
Create a member variable for if hover is true and use that in the paint method to figure out which image to paint.
I want to indicate status of a station by marking color over a region. Graphics2D class is used to draw color. It has to be updated continuously. I am using timer but it is not working. Any help is appreciated.
import javax.swing.*;
import java.awt.*;
import redis.clients.jedis.Jedis;
public class Station1 {
public Station1(){
Gradient gradient = new Gradient();
JFrame f = new JFrame("Input Carousel");
f.setLayout(new BorderLayout());
JLabel label = new JLabel();
ImageIcon icon = new ImageIcon(getClass().getResource("images/input carousel.jpg"));
label.setIcon(icon);
gradient.add(label);
f.add(gradient);
f.pack();
f.setResizable(false);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public static void main(String args[]){
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new Station1();
}
});
}
class Gradient extends JPanel{
public Graphics2D g2D ;
#Override
public void paintComponent(Graphics g){
g2D = (Graphics2D)g;
AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
g2D.setComposite(alphaComposite);
new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
try{
Jedis jedis = new Jedis("localhost");
if(jedis.get("b1").equals("1"))
{
g2D.setColor(Color.GREEN);
g2D.fillRect(208, 172, 47, 75);
}
else if(jedis.get("b1").equals("e"))
{
g2D.setColor(Color.RED);
g2D.fillRect(208, 172, 47, 75);
}
}
catch(Exception e)
{
}
}
}).start();
}
}
}
If I run the code without timer it is working. If I use timer, it will not draw any color.
Please suggest me solution for this problem.
You've several glaring issues with that code:
Starting a Timer within a painting method, a method that often gets called many times, most of which you have no control over
Calling what looks like potentially blocking code within a painting method (and within the Swing event thread). This may render your code completely useless as this can potentially freeze the gui
Suggestions:
Create the Timer and start it once and not within any painting method. Perhaps do this within a class's constructor
The timer should change fields of the class and call repaint
Your painting method should then use the state of these fields to decide what to paint and where
Don't forget to call the super.paintComponent(g); in your override, usually on its first line.
If creating Jedis means creating a long-running bit of code, do this within a background thread such as a SwingWorker
A painting method is for painting and painting only, and your code should respect this.
For example, please have a look at the code below. Note that I do not have access to your Jedis class (nor why you're using it), and so created a "mock" class. Also, I do not have access to your image, and so used a publicly available image for this demo program. I also sped up your timer.
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
// import redis.clients.jedis.Jedis;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
public class Station1 {
private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/"
+ "commons/thumb/f/f4/LINCOLN%2C_Abraham-President_%28BEP_engraved_portrait%29.jpg"
+ "/800px-LINCOLN%2C_Abraham-President_%28BEP_engraved_portrait%29.jpg";
public Station1() {
Gradient gradient = new Gradient();
JFrame f = new JFrame("Input Carousel");
f.setLayout(new BorderLayout());
JLabel label = new JLabel();
// ImageIcon icon = new ImageIcon(getClass().getResource("images/input carousel.jpg"));
BufferedImage img = null;
try {
URL imgUrl = new URL(IMG_PATH);
img = ImageIO.read(imgUrl);
} catch (IOException e) {
e.printStackTrace();
}
Icon icon = new ImageIcon(img);
label.setIcon(icon);
gradient.add(label);
f.add(gradient);
f.pack();
f.setResizable(false);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Station1();
}
});
}
#SuppressWarnings("serial")
class Gradient extends JPanel {
private JedisMock jedisMock = new JedisMock("localhost");
private String jedisValue = "";
public Gradient() {
int timerDelay = 200;
new Timer(timerDelay, new TimerListener()).start();
}
private class TimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
// may need to wrap this within a try/catch
jedisValue = jedisMock.get("b1");
repaint();
}
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
0.5f);
g2D.setComposite(alphaComposite);
if (jedisValue.equals("1")) {
g2D.setColor(Color.GREEN);
g2D.fillRect(208, 172, 47, 75);
} else if (jedisValue.equals("e")) {
g2D.setColor(Color.RED);
g2D.fillRect(208, 172, 47, 75);
}
}
}
}
public class JedisMock {
private String host;
public JedisMock(String host) {
this.host = host;
}
public String getHost() {
return host;
}
// method to mock your method
public String get(String text) {
double randomValue = Math.random();
if (randomValue < 0.333) {
return "1";
} else if (randomValue < 0.667) {
return "e";
} else {
return "";
}
}
}
trying to create a rectangle using paint but repaint method's not calling paint method.
even tried replacing paint with paintComponent, but still not working.
So what changes to make to make it work.
is there a problem with calling repaint method in run.
is there a problem with the instance.
trying to create a rectangle using paint but repaint method's not calling paint method.
even tried replacing paint with paintComponent, but still not working.
So what changes to make to make it work.
is there a problem with calling repaint method in run.
is there a problem with the instance.
package src;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
public class main extends JFrame implements Runnable{
private final int Height = 480;
private final int Width = 640;
Thread gameloop;
public static main instance = null;
private main(){
JFrame frame = new JFrame();
frame.setSize(this.Width,this.Height);
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public static main getInstance(){
if (instance == null){
instance = new main();}
return instance;
}
private void start(){
gameloop = new Thread(this);
gameloop.start();
}
#Override
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(g2d.getBackground());
g2d.fillRect(0, 0, instance.Width, instance.Height);
g2d.setColor(Color.red);
g2d.fillRect(0, 0, 50, 50);
}
#Override
public void run() {
Thread current = Thread.currentThread();
while (gameloop == current){
try{
Thread.sleep(5);
}
catch (InterruptedException e){
e.printStackTrace();
}
repaint();
}
}
public static void main(String[] args){
main.getInstance();
main.getInstance().start();
}
}
The original problem was that you created a new JFrame in your constructor and then made that visible, instead of using the main instance you just created, so nothing in your main class was actually being displayed in your app, just a blank JFrame that does nothing. Also your run loop made no sense.
However, your code has a lot of other problems, both in logic and style. I'd advise you to just refactor everything. Here's a cleaner version that also solves your problem.
package src;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
public final class Main extends JFrame implements Runnable {
private volatile boolean running;
private Main(int width, int height) {
setSize(width, height);
setVisible(true);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void start() {
running = true;
new Thread(this).start();
}
private void stop() {
running = false;
}
#Override
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(g2d.getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.setColor(Color.red);
g2d.fillRect(0, 0, 50, 50);
}
#Override
public void run() {
while (running) {
try {
Thread.sleep(40);
}
catch (InterruptedException e){
e.printStackTrace();
}
repaint();
}
}
public static void main(String[] args) {
new Main(640, 480).start();
}
}
I am having a problem with the code below. If I load the image directly into the JPanel I can see it. But when I try to draw it first to the BufferedImage before drawing the BufferedImage on the JPanel the image is not visible. What am I doing wrong?
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import java.awt.*;
import javax.swing.JPanel;
/**
*
* #author Duafeb
*/
public class RTester {
BufferedImage backBuffer;
Graphics2D g2;
Pane pain;
Image img;
public RTester(){
JFrame frame=new JFrame("Sprite Tester");
frame.setSize(1200, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
backBuffer= new BufferedImage(1200,700,BufferedImage.TYPE_INT_RGB);
g2=backBuffer.createGraphics();
pain=new Pane();
frame.add(pain);
Toolkit tk=Toolkit.getDefaultToolkit();
img=tk.getImage(this.getClass().getResource("running.png"));
frame.setVisible(true);
}
public class Pane extends JPanel{
#Override
public void paintComponent(Graphics g){
Graphics2D g3=(Graphics2D)g;
g3.drawImage(backBuffer, 0, 0, this);
}
}
public void display(){
g2.setColor(Color.yellow);
g2.fillRect(0, 0, pain.getWidth(), pain.getHeight());
g2.drawImage(img, 0, 0, pain);
pain.repaint();
}
public static void main(String[] args){
RTester test=new RTester();
test.display();
}
}
There are a few things that don't feel right about this...
The first is, you create a Graphics context to BufferedImage, but never dispose of it. Be careful, on some systems this can prevent the contents from been rendered, but this might relate to the screen device rather than a BufferedImage
For example, if I alter you code to paint the contents directly within the paintComponent method instead of to the BufferedImage, the image will be displayed (all bit a split second after the window becomes visible).
I'm not sure what it is you're trying to achieve by using the BufferedImage, but you could achieve the same thing straight through the paintComponent method
Instead of using Toolkit.getImage, you could use ImageIO.read, which guarantees that when it returns, the image is fully loaded (or will throw an IOException if it fails) or as #Reimeus had previously suggested, using a MediaTracker to ensure that the image is properly loaded before you continue using it.
So, you have four options....
One
Use a MediaTracker to wait for the image to be loaded...
MediaTracker mt = new MediaTracker(frame);
mt.addImage(img, 1);
try {
mt.waitForAll();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
Two
Use ImageIO.read instead...
img = ImageIO.read(this.getClass().getResource("running.png"));
Three
Render output directly in the paintComponent method...
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g3 = (Graphics2D) g;
g3.setColor(Color.yellow);
g3.fillRect(0, 0, pain.getWidth(), pain.getHeight());
g3.drawImage(img, 0, 0, obsever);
}
Four
Use you own ImageObserver to ensure that when the image is updated, you re-render it to the backing buffer...
private MyImageObsever obsever;
public void display() {
if (obsever == null) {
obsever = new MyImageObsever(this);
}
g2.setColor(Color.yellow);
g2.fillRect(0, 0, pain.getWidth(), pain.getHeight());
g2.drawImage(img, 0, 0, obsever);
pain.repaint();
}
public class MyImageObsever implements ImageObserver {
private RTester tester;
public MyImageObsever(RTester tester) {
this.tester = tester;
}
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
tester.display();
return (infoflags & (ALLBITS|ABORT)) == 0;
}
}
So I have this login form and I have a "user photo." I'm trying to make it so that when you hover the mouse over the photo area, a transparent label with a colored background will appear (to give the effect of "selecting the photo"). It looks like this:
And once you move your mouse off it, it goes back to being "deselected."
Now my problem is, if you hover your mouse over the login button first then move your mouse over the photo, a "ghost login button" appears. It looks like this:
I don't know why this is happening. Can someone help? Here is the relevant code:
package com.stats;
public class Stats extends JFrame implements Serializable {
private JLabel fader;
public Stats() {
try {
Image image = ImageIO.read(new File(System.getenv("APPDATA")
+ "\\Stats\\Renekton_Cleave.png"));
JLabel labelUserPhoto = new JLabel(new ImageIcon(image));
fader = new JLabel();
fader.setBounds(97, 44, 100, 100);
fader.setOpaque(true);
fader.setBackground(new Color(0, 0, 0, 0));
labelUserPhoto.setBounds(97, 44, 100, 100);
PicHandler ph = new PicHandler();
contentPane.add(fader);
contentPane.add(labelUserPhoto);
fader.addMouseMotionListener(ph);
} catch(Exception e) {
e.printStackTrace();
}
}
private class PicHandler implements MouseMotionListener {
public void mouseDragged(MouseEvent e) { }
public void mouseMoved(MouseEvent e) {
int x = e.getX();
int y = e.getY();
System.out.println("x: " + x + ", y: " + y);
if ((x > 16 && x < 80) && (y > 16 && y < 80)) {
if (!fader.isOpaque()) {
fader.setOpaque(true);
fader.setBackground(new Color(0, 0, 0, 40));
fader.repaint();
}
} else {
if (fader.isOpaque()) {
fader.setOpaque(false);
fader.repaint();
}
}
}
}
I can see a number of issues with your example, but the most significant is the use of a color with an alpha value.
fader.setBackground(new Color(0, 0, 0, 40));
Swing doesn't render components with alpha based colors well (within this context). By making component opaque and then setting the background color to use an alpha value, you are telling Swing that it doesn't need to worry about painting what's underneath your component, which isn't true...
The Graphics context is also a shared resource, meaning that anything that was painted before your component is still "painted", you need to clear the Graphics context before painting.
This example uses a rather nasty trick to get it's work done. Because all the painting occurs within the UI delegate, if we were simply to allow the default paint chain to continue, we wouldn't be able to render underneath the icon. Instead, we take over control of the "dirty" details and paint the background on the behalf the parent.
This would be simpler to achieve if we simple extended from something like JPanel and painted the image ourselves
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FadingIcon {
public static void main(String[] args) {
new FadingIcon();
}
public FadingIcon() {
startUI();
}
public void startUI() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
BufferedImage img = null;
try {
img = ImageIO.read(new File("C:\\Users\\swhitehead\\Documents\\My Dropbox\\Ponies\\SmallPony.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setLayout(new GridBagLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new FadingLabel(new ImageIcon(img)));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class FadingLabel extends JLabel {
private boolean mouseIn = false;
private MouseHandler mouseHandler;
public FadingLabel(Icon icon) {
super(icon);
setBackground(Color.RED);
super.setOpaque(false)(
}
#Override
public void setOpaque(boolean opaque) {
}
#Override
public final boolean isOpaque() {
return false;
}
protected MouseHandler getMouseHandler() {
if (mouseHandler == null) {
mouseHandler = new MouseHandler();
}
return mouseHandler;
}
#Override
public void addNotify() {
super.addNotify();
addMouseListener(getMouseHandler());
}
#Override
public void removeNotify() {
removeMouseListener(getMouseHandler());
super.removeNotify();
}
#Override
protected void paintComponent(Graphics g) {
if (mouseIn) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
g2d.dispose();
}
getUI().paint(g, this);
}
public class MouseHandler extends MouseAdapter {
#Override
public void mouseEntered(MouseEvent e) {
mouseIn = true;
repaint();
}
#Override
public void mouseExited(MouseEvent e) {
mouseIn = false;
repaint();
}
}
}
}
I would also recommend that you take the time to learn how to use appropriate layout managers, they will save you a lot of hair pulling later
Check out A Visual Guide to Layout Managers and Laying Out Components Within a Container
Since I can't comment I have to put this as an answer:
As trashgod mentioned, this problem can be caused by a missing super.paintComponent(g) call however you don't seem to be overriding the paintComponent method at all (at least you didn't show it here). If you do override the paintComponent method of a JFrame or any JPanels, you need to have:
public void paintComponent(Graphics g) {
super.paintComponent(g);
//rest of your drawing code....
}
But if you haven't used one at all then the problem may be caused by something else.
Since jdk7 there a new mechanism to apply visual decorations (and listening to events for child components): that's the JLayer/LayerUI pair.
In your case a custom layerUI would
trigger a repaint on rollover
implement the paint to apply the transparent color
Below is an example, similar to the WallPaperUI in the tutorial:
// usage: create the component and decorate it with the custom ui
JLabel label = new JLabel(myIcon);
content.add(new JLayer(label, new RolloverUI()));
// custom layerUI
public static class RolloverUI extends LayerUI<JComponent> {
private Point lastMousePoint;
private JLayer layer;
/**
* Implemented to install the layer and enable mouse/motion events.
*/
#Override
public void installUI(JComponent c) {
super.installUI(c);
this.layer = (JLayer) c;
layer.setLayerEventMask(AWTEvent.MOUSE_MOTION_EVENT_MASK
| AWTEvent.MOUSE_EVENT_MASK);
}
#Override
protected void processMouseMotionEvent(MouseEvent e,
JLayer<? extends JComponent> l) {
updateLastMousePoint(e.getPoint());
}
#Override
protected void processMouseEvent(MouseEvent e,
JLayer<? extends JComponent> l) {
if (e.getID() == MouseEvent.MOUSE_EXITED) {
updateLastMousePoint(null);
} else if (e.getID() == MouseEvent.MOUSE_ENTERED) {
updateLastMousePoint(e.getPoint());
}
}
/**
* Updates the internals and calls repaint.
*/
protected void updateLastMousePoint(Point e) {
lastMousePoint = e;
layer.repaint();
}
/**
* Implemented to apply painting decoration below the component.
*/
#Override
public void paint(Graphics g, JComponent c) {
if (inside()) {
Graphics2D g2 = (Graphics2D) g.create();
int w = c.getWidth();
int h = c.getHeight();
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, .5f));
g2.setPaint(new GradientPaint(0, 0, Color.yellow, 0, h,
Color.red));
g2.fillRect(0, 0, w, h);
g2.dispose();
}
super.paint(g, c);
}
protected boolean inside() {
if (lastMousePoint == null || lastMousePoint.x < 0
|| lastMousePoint.y < 0)
return false;
Rectangle r = layer.getView().getBounds();
r.grow(-r.width / 10, -r.height / 10);
return r.contains(lastMousePoint);
}
}
I had a similar problem with ghosted images after something moved or was resized.
#MadProgrammer has some really good points, but in the end, they didn't work for me (possibly because I had multiple layers using 0.0 alpha value colors, some of which also had images in them, so I couldn't set a composite value for the whole component). In the end, what fixed it was a simple call to
<contentpane>.repaint()
after all the draw commands were executed.