javaswingjlabel

Add an image with JLabel without loss of quality


so I just started learning Java (have some C++ experience) and I'm having some trouble. I never created a GUI, so I'm experimenting with it right now, while learning Java at the same time. The issue I have right now is that I can't figure out a way how to add an image with JLabel without loss of quality. Every method I tried, using Graphics 2D, Thumbnailator, BufferedImage gets me the same result. It feels like image loses it's sharpness from the original one.

I have looked for solutions, I really did, but most of them are really old or really hard to understand. So, I'm asking for help where, if you can, explain it to me like I'm five.

This is how I import an image right now, as it seems like the easiest method.

ImageIcon logo = new 
ImageIcon(this.getClass().getResource("logo.png"));

    logoLabel.setIcon(logo);
    logoLabel.setPreferredSize(new Dimension(logo.getIconWidth(), 
    logo.getIconHeight()));

But I'm sure there are other methods. Thanks for the help in advance.

I'm on Windows 11 Home 22H2, using IntelliJ Community Edition 232.10203.10 with Java 11.0.20

Full code:

 import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class GUI implements ActionListener {

    private int count = 0;
    private JLabel label;
    private JFrame frame;
    private JPanel panel;
    private JButton button;
    public GUI() {
        frame = new JFrame();
        button = new JButton("Click me");
        label = new JLabel("Number of clicks: 0");
        panel = new JPanel();
        JLabel logoLabel = new JLabel();
        ImageIcon logo = new ImageIcon(this.getClass().getResource("logo.png"));
        Dimension buttonDim = new Dimension(100, 40);

        logoLabel.setIcon(logo);

        button.addActionListener(this);
        button.setPreferredSize(buttonDim);

        panel.setBorder(BorderFactory.createEmptyBorder(30, 30, 10, 30));
        panel.add(button);
        panel.add(label);
        panel.add(logoLabel);

        frame.setSize(1100, 900);
        frame.add(panel, BorderLayout.CENTER);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Our GUI");
        frame.setVisible(true);
    }
    public static void main(String[] args) {
        new GUI();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        count++;
        label.setText("Number of clicks: " + count);
    }
}

Original image:

enter image description here

What I get in the GUI

enter image description here

I'm not resizing it or anything.


Solution

  • So, after updating Java to OpenJDK 21, it still wasn't solved. The real issue actually was with my own system. As I'm using a laptop with QHD screen, it's not comfortable to use it at 100% scaling so I set it to 125%. This was causing the issue. The solution was to add a VM option to the IDE

    -Dsun.java2d.uiScale=1.0
    

    This is what worked for me. Thanks everyone for giving ideas on how to solve it!