0

I have an application with a Swing GUI and I would like to add a search-field with a search-button (lupe icon) to the menu bar. However, the lupe icon won't display. Here is my code:

public class Ui_Frame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(Ui_Frame::createAndShowGUI);
    }
    

    private static void createAndShowGUI() {
         f = new JFrame("Myframe"); 

         ...

         JMenuBar menubar = new JMenuBar();
         Icon lupeIcon = new ImageIcon("Resources/lupe_icon.png");
         JButton j_searchButton = new JButton(lupeIcon);
         menubar.add(j_searchButton);

         ...

         f.setJMenuBar(menubar);
         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         f.pack();
         f.setVisible(true);

My project structure is like

Project 
       Src
          Ui_Frame.java
          Resources 
                 lupe_icon.png 

The resulting button shows no icon at all :

enter image description here

I do not get any error message, it compiles without problems. Even when I try to catch any exception from the new ImageIcon(...) I'm not getting any hint at what the error is.

Any ideas as to what Im doing wrong here?

EDIT:

Here is a minimal example:

import javax.swing.*;

public class test {

    private static JFrame f;

    public static void main(String[] args) {
        SwingUtilities.invokeLater(test::createAndShowGUI);
    }

    private static void createAndShowGUI() {

        f = new JFrame("Test");
        JMenuBar menubar = new JMenuBar();

        Icon lupeIcon = new ImageIcon(test.class.getResource("/Resources/lupe_icon.png"));
        JButton j_searchButton = new JButton(lupeIcon);
        menubar.add(j_searchButton);

        f.setJMenuBar(menubar);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setSize(500,500);
        f.setVisible(true);
    }
}

As you can see I am now loading the image with class.getResource(...) as was suggested by @AndrewThompson and @SergiyMedvynskyy, but that does not solve the problem. Also I was told that my classes should not be static, but since my Main needs to be static for me to be able to run the program and I have been told that I should start the UI with SwingUtilities.invokeLater(test::createAndShowGUI); which also forces createAndShowGUI() to be static, I do not know how to make it not static.

krise
  • 485
  • 1
  • 10
  • 22
  • Seems like it could be an issue loading the resource. Can you check if `lupeIcon` is null? – maloomeister Sep 01 '20 at 07:29
  • @maloomeister I checked, it is not null. – krise Sep 01 '20 at 07:42
  • Probably you should load your Icon via `new ImageIcon(Ui_Frame.class.getResource("Resources/lupe_icon.png"));` – Sergiy Medvynskyy Sep 01 '20 at 07:44
  • @SergiyMedvynskyy Okay I tried that, did not solve problem :( . Do I maybe need to format my lupe_icon.png in any special way? At the moment its just some png I downloaded – krise Sep 01 '20 at 07:57
  • 1) Application resources will become embedded resources by the time of deployment, so it is wise to start accessing them as if they were, right now. An [tag:embedded-resource] must be accessed by URL rather than file. See the [info. page for embedded resource](http://stackoverflow.com/tags/embedded-resource/info) for how to form the URL. 2) For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 3) One way to get image(s) for an example is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). .. – Andrew Thompson Sep 01 '20 at 08:00
  • .. E.G. [This answer](https://stackoverflow.com/a/10862262/418556) hot links to an image embedded in [this question](https://stackoverflow.com/q/10861852/418556). 4) `private static void createAndShowGUI()..` I've never had success loading resources in a static method. Doing it successfully requires access to the application, or context, class loader, and that is easiest done by starting from an instance of a custom class (e.g. the main app). – Andrew Thompson Sep 01 '20 at 08:00
  • @AndrewThompson Alright, I have added a minimal example. – krise Sep 01 '20 at 08:33
  • OK ..first check the resource is included in the Jar the IDE is making. If you run Windows it's easy. (Make a copy of and) rename the Jar to a .zip, then double click to open & explore. Is the image included? Is it located on the expected path? – Andrew Thompson Sep 01 '20 at 09:30
  • Did you solve the problem? – Andrew Thompson Sep 07 '20 at 11:39
  • Yes, I posted an answer – krise Sep 07 '20 at 14:29

2 Answers2

3

For me it's working without mention folder "Resources" in the path, like that:

Icon lupeIcon = new ImageIcon(test.class.getResource("/lupe_icon.png"));

But, i'm not sure your project structure is correct.

If still doesn't work, try rename folder with small 'r', and maybe also change project structure, this is my structure:

\src\main\java... (all java files)

\src\main\resources (resources folder, it displayed for me like a package)

Note - i think best is to check why u can't get the image in debug

Adir Dayan
  • 1,308
  • 13
  • 21
  • You can also look at this lib - https://github.com/oleg-cherednik/IconManager. I have created it years ago just for this case. – Oleg Cherednik Sep 01 '20 at 19:47
0

After switching to Icon lupeIcon = new ImageIcon(test.class.getResource("Resources/lupe_icon.png")); to load the icon instead of new ImageIcon("Resources/lupe_icon.png"); I noticed that I was getting nullpointer-exceptions, despite the image clearly being there. After some googling I found out that the resource folder apparently is not just any folder but has to be marked as the resource root folder, as suggested here.

After marking the folder everything works fine :)

krise
  • 485
  • 1
  • 10
  • 22