Search code examples
javaswingjframeimageicon

JFrame's default icon showing intermittently in Win taskbar during dynamic updates


I am dynamically updating the icon of a JFrame but in the task bar the default icon (cup of coffee) is showing every few seconds, is there any way to disable it?

First I set a default custom icons:

frame.setIconImage

And then update the icon every 100 ms. Tested in Win 7/8/10 (oracle jdk 8 and 10) - same behaviour.

This is for my audio player to visualise audio waves.

enter image description here

Any way to fix it?

Sample code:

package test;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;
import javax.swing.JFrame;

public class TestFrameIcon {

    static BufferedImage img = new BufferedImage(64, 64, BufferedImage.TYPE_4BYTE_ABGR);
    static Random r = new Random();

    private static BufferedImage getIcon() {
        Graphics g = img.getGraphics();
        g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
        g.fillRect(0, 0, img.getWidth(), img.getHeight());
        g.dispose();
        return img;
    }

    public static void main(String[] args) {
        JFrame f = new JFrame();

        f.setIconImage(getIcon());
        f.setSize(100, 100);
        f.setLocationRelativeTo(null);

        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        new Thread(() -> {
            while (true) {
                f.setIconImage(getIcon());
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                }
            }
        }).start();;
        f.setVisible(true);
    }

}

Every few seconds it is showing a default icon in the task bar:

enter image description here


Solution

  • The code provided keeps reusing the same BufferedImage, the one that's already in use.

    Try allocating a new BufferedImage for each update. Don't worry too much about creating lots of crap on the heap, it will get cleaned up quickly. If you absolutely require no extra objects on the heap, swap between two BufferedImages.