0

I could use some help regarding the setting of an icon on a JFrame. I have a Java 8 application that is typically used in both Windows and Linux environments. The application is composed of a number of "SFrames", which are a custom class that extends a JFrame and includes the setting of a custom icon for the frame. There is one main "SFrame" for the application, and then other "SFrames" are brought up as needed depending on the actions of the user. All "SFrames" have the same icon displayed.

In the past when running this application on both Windows and Linux the correct icon appeared on all "SFrames" (the main application "SFrame", and then all subsequent frames that were brought up). The execution environment for Linux was recently updated from an older version of Fedora (with the Mate desktop environment) to a recent version of Red Hat Enterprise Linux (also with the Mate desktop environment). In this new Linux environment the icon was not appearing on any of the "SFrames", either the main frame or any subsequent frames that appear.

I did see this Stackoverflow entry (JFrame icon not displaying in Ubuntu 12.04), and setting setDefaultLookAndFeelDecorated to "true" in the "SFrame" constructor does cause the icon to appear on subsequent SFrames that are brought up under Linux, but not the first frame. The first SFrame continues to have no icon on it, and appears very similar to the default appearance of other Mate windows. Later experimentation showed that it is always the first SFrame that is left at the default appearance with no icon, regardless of whether subsequent SFrames are called from the first SFrame (i.e., subsequent SFrames are like "children" of the first SFrame, as shown in the example below), or whether multiple SFrames are called sequentially (i.e., subsequent SFrames are like "younger siblings" of the first SFrame).

With the minimum reproducible example given below, the attached graphic shows the results on Windows and Linux. For Windows, both SFrames have an icon displayed, in this case the letter "A". These results are produced on Windows regardless of whether the call to setDefaultLookAndFeelDecorated is made or not. For Linux, the first SFrame is displayed with no icon, the second SFrame with an icon. If the call to setDefaultLookAndFeelDecorated is not made then neither SFrame has the icon on Linux.

Graphic: click here

import javax.swing.*;

class SFrame extends JFrame {

     private static final ImageIcon image = new ImageIcon("icon.png");

     public SFrame() {

        setDefaultLookAndFeelDecorated(true);
        
        if (image != null)
        {
         setIconImage(image.getImage());
        }

     }
}


class ChildFrame extends SFrame {
   
     public ChildFrame() {
         
        // Dimensions set so two windows do not overlap
        setBounds(350, 100, 200, 400);
        setTitle("CHILD");
                
    }
}

public class MinimumExample extends SFrame {

    private SFrame childFrame_;
  
    public MinimumExample() {
        
        // Dimensions set so two windows do not overlap
        this.setBounds(100, 100, 200, 400);
        this.setTitle("PARENT");
        this.setVisible(true);
      
        childFrame_ = new ChildFrame();
        childFrame_.setVisible(true);
   }

    public static void main(String args[]) {

        new MinimumExample();
    }

}


Could somebody point me in the right direction for a fix? Thanks

Tompac
  • 1
  • 2
  • 1. Confirm that on Linux it will display an icon at all for a "normal" `JFrame`. I'm not sure how you're doing it, but the child frames seem to be using a customised look and feel and/or frame delegate; 2. I'd look at [`JFrame#setIconImages`](https://docs.oracle.com/en/java/javase/17/docs/api/java.desktop/java/awt/Window.html#setIconImages(java.util.List)) which allows you to supply a number of differently sized icons which might help ([for example](https://stackoverflow.com/questions/18224184/sizes-of-frame-icons-used-in-swing)) – MadProgrammer Jul 11 '23 at 01:19
  • MadProgrammer, thanks for the comments. I made another minimum example that got rid of the SFrame and ChildFrame classes entirely. I created two JFrames and then added icons to both. Under Linux the first JFrame does not get the icon but the second JFrame does. Both JFrames look identical to what is shown for Linux in the graphic I posted earlier. – Tompac Jul 11 '23 at 02:16

1 Answers1

0

So, apparently instantiating the first JFrame (or SFrame) without assigning it to a variable does not work properly as far as assigning the icon. I found that if I declared a JFrame/SFrame variable first, called setDefaultLookAndFeelDecorated(true) on that JFrame/SFrame variable before even instantiating the object, and then instantiated the JFrame/SFrame and assigned it to the variable that things work as desired (the first JFrame/SFrame does get the icon). I can't say I understand why I need to do that, but I do get the behavior that I want.

Tompac
  • 1
  • 2
  • I've run into very similar issue with the JFrame icon not being shown in the Ubuntu dock (in certain situations). Ubuntu 22.04 solved it. It was very finicky, order and timing dependent. Good to hear you figured out what to tweak to work around the problem. – Trevor Harrison Jul 11 '23 at 03:55