Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8253530

HiDPI with non-integer scaling causes artifacts

XMLWordPrintable

      A DESCRIPTION OF THE PROBLEM :
      When using non-integer HiDPI scaling (such as 125%, a common setting on Windows), graphical corruption can appear around the borders of components like JButton depending on their positions.

      In the given example, there are three JButtons that are each 26 units tall inside a JPanel that is 26*3 = 78 units tall. At 125% scaling each button ends up at 32 pixels, but the pane ends up at 97 pixels with a one pixel gap between the second and third buttons. This gap contains garbage data that problem the second button was expected to write but didn't.

      Note that the clip bounds for these buttons may be calculated as 26 or 27 height depending on their exact positions (due to floating point precision issues when applying the inverse scaling transform), although this appears to be clamped to height, at least one place.

      Border drawing using -1 in unscaled space also seems dubious and could be related.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the provided code with 125% dpi scaling.

      The garbage is not always noticeable. In the given example, I usually see noticeable garbage after hovering Button 2.

      This example seems sensitive to the exact positions of the elements (although many arrangements can cause this kind of problem). In case this is not consistent between systems, the positions on my system are (x,y,w,h):
      container: 0,0,152,88
      panel: 35,5,82,78
      button 1: 0,0,82,26
      button 2: 0,26,82,26
      button 3: 0,52,82,26

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      There is no gap between the buttons.
      ACTUAL -
      There is a one pixel gap between Button 2 and Button 3. In this gap, the screen contains garbage.

      Screenshot: https://imgur.com/RVYgYty

      ---------- BEGIN SOURCE ----------
      import javax.swing.*;

      public class Test {

          public static void main(String[] args) {
              JPanel container = new JPanel();
              JPanel panel = new JPanel();
              panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
              for(int i = 1; i <= 3; i++) panel.add(new JButton("Button " + i));
              JFrame frame = new JFrame();
              container.add(panel);
              frame.add(container);
              frame.pack();
              frame.setVisible(true);
          }
        
      }
      ---------- END SOURCE ----------

      FREQUENCY : always


        1. Capture.JPG
          Capture.JPG
          52 kB
        2. Test.java
          0.5 kB

            psadhukhan Prasanta Sadhukhan
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated: