1

I need to create an application with interface scaling. I have a button with icon inside and jpanel, that hold this button. The problem is that when scale is on - an icon is blurred and to fix this, I use downscaling in paintComponent. When system scale is on, I have normal image, as a result. But JPanel still have a scaled size. I tryed to override JPanel paintComponent too, but as a result I had too small buttons, because downscale on button and donwscale on JPanel work togeather. I can't use scale only from JPanel, when I click a button, it take a scaled size and image blurred again. This is a simple example.

enter image description here

And the code is:

public class Test{

public static void main(String[] args) throws Exception{

    System.setProperty("sun.java2d.uiScale", "1.5");
    JFrame j = new JFrame();
    Image img = ImageIO.read(new File("D:\\1.png"));
    j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    j.setPreferredSize(new Dimension(300, 150));
    j.setVisible(true);
    j.setLocationRelativeTo(null);
    j.setLayout(new BorderLayout());

    img = img.getScaledInstance((int) (60 * 1.5),(int) (60 * 1.5),Image.SCALE_DEFAULT);

    JToggleButton tb = new JToggleButton(){
        @Override
        protected void paintComponent(Graphics g) {

            Graphics2D g2 = (Graphics2D) g;
            g2.scale(0.67,0.67);
            super.paintComponent(g2);
        }
    };
    tb.setIcon(new ImageIcon(img));

    JToggleButton tb2 = new JToggleButton(){
        @Override
        protected void paintComponent(Graphics g) {

            Graphics2D g2 = (Graphics2D) g;
            g2.scale(0.67,0.67);
            super.paintComponent(g2);
        }
    };
    tb2.setIcon(new ImageIcon(img));


    JPanel jPanel = new JPanel(){

    };
    jPanel.setLayout(new GridLayout(1,1));
    jPanel.add(tb);
    jPanel.setBackground(Color.RED);



    JPanel content = new JPanel();
    content.setLayout(new FlowLayout());
    content.add(jPanel);

    j.setContentPane(content);
    j.pack();
}

} I use java10. Thank you.

c0der
  • 18,467
  • 6
  • 33
  • 65
  • Scaling is complicated, as it affects more things then just the rendering of the graphics, it effects the coordinate system as well. I think, as a generally better solution, you will want to scale the icons independently based on the system scale – MadProgrammer Jul 30 '18 at 05:33
  • 1
    You might want to have a look at [Java 9 hdpi display support - multi-resolution images - name convention and loading in Windows](https://stackoverflow.com/questions/38802885/java-9-hdpi-display-support-multi-resolution-images-name-convention-and-load) – MadProgrammer Jul 30 '18 at 05:52
  • If I will independently scale image, it been scale again from system scale. – Алексей Босак Jul 30 '18 at 08:48

1 Answers1

1

You render your UI with scaling factor of 1.5: all UI including icons and images is scaled so that it displays correctly on a High DPI display. If image does not scale, it would be too small for a higher DPI setting.

If your application supports High DPI displays, i.e. UI scaling, you should provide images of different resolutions. See MultiResolutionImage in Java 9.

You can find sample code in this answer to a related question.

Alexey Ivanov
  • 11,541
  • 4
  • 39
  • 68
  • [My answer](https://stackoverflow.com/a/71101882/572834) to another question includes the sample which demonstrates the usage of `MultiResolutionImage`. – Alexey Ivanov Feb 15 '22 at 21:18