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

JSlider has wrong preferred size with Synth LAF

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P3
    • 9
    • 7u45, 9
    • client-libs
    • b59
    • windows_7

    Backports

      Description

        FULL PRODUCT VERSION :
        java version "1.7.0_45"
        Java(TM) SE Runtime Environment (build 1.7.0_45-b18)
        Java HotSpot(TM) 64-Bit Server VM (build 24.45-b08, mixed mode)

        ADDITIONAL OS VERSION INFORMATION :
        Win7 64Bit

        A DESCRIPTION OF THE PROBLEM :
        When using a Synth based look and feel JSlider returns the wrong preferred size. Which means the height is not correct for horizontal sliders and the width is not correct for vertical sliders.

        REGRESSION. Last worked in version 6u43

        ADDITIONAL REGRESSION INFORMATION:
        java version "1.6.0_31"
        Java(TM) SE Runtime Environment (build 1.6.0_31-b05)
        Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01, mixed mode)

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Execute the posted test - if the slider insets in the XML section are set to 0 0 0 0 the preferred size is 200,36 on Java 6/7/8, this is OK. When the insets are changed to 5 5 5 5 width and height should be increased by 10.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        For insets 5 5 5 5 width and height should be increased by 10. So the expected result is 210, 46.
        ACTUAL -
        On Java 6 the height is OK - result 200, 46.
        On Java 7/8 the width is OK, - result 210, 56. Means the top/bottom insets are added twice.

        The issue seams to be caused by SynthSliderUI#getPreferredSize(). In Java 7/8 the insets will be added at the end of method - but for horizontal sliders the insets are already respected by contentRect, same for the width of vertical sliders.

            public Dimension getPreferredSize(JComponent c) {
                recalculateIfInsetsChanged();
                Dimension d = new Dimension(contentRect.width, contentRect.height);
                if (slider.getOrientation() == JSlider.VERTICAL) {
                    d.height = 200;
                } else {
                    d.width = 200;
                }
                Insets i = slider.getInsets();
                d.width += i.left + i.right;
                d.height += i.top + i.bottom;
                return d;
            }

        So changing the code just like below should finally fix the issue

            public Dimension getPreferredSize(JComponent c) {
                recalculateIfInsetsChanged();
                Dimension d = new Dimension(contentRect.width, contentRect.height);
                Insets i = slider.getInsets();
                if (slider.getOrientation() == JSlider.VERTICAL) {
                    d.height = 200 + i.top + i.bottom;
                } else {
                    d.width = 200 + i.left + i.right;;
                }
                return d;
            }


        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import java.awt.Dimension;
        import java.awt.FlowLayout;
        import java.io.ByteArrayInputStream;
        import java.io.InputStream;

        import javax.swing.JFrame;
        import javax.swing.JLabel;
        import javax.swing.JSlider;
        import javax.swing.UIManager;
        import javax.swing.plaf.synth.SynthLookAndFeel;

        public class SynthSliderTest extends JFrame
        {
          private static String synthXml = "<synth>" +
          " <style id=\"all\">" +
          " <font name=\"Segoe UI\" size=\"12\"/>" +
          " <state>" +
          " <color value=\"GRAY\" type=\"BACKGROUND\"/>" +
          " <color value=\"BLACK\" type=\"FOREGROUND\"/>" +
          " <color value=\"WHITE\" type=\"TEXT_FOREGROUND\"/>" +
          " </state>" +
          " </style>" +
          " <bind style=\"all\" type=\"REGION\" key=\".*\"/>" +
          " <style id=\"slider\">" +
          " <insets top=\"5\" left=\"5\" bottom=\"5\" right=\"5\"/>" +
          //" <insets top=\"0\" left=\"0\" bottom=\"0\" right=\"0\"/>" +
          " <state>" +
          " <opaque value=\"true\"/>" +
          " <color type=\"BACKGROUND\" value=\"#AAAAAA\" />" +
          " </state>" +
          " </style>" +
          " <bind style=\"slider\" type=\"region\" key=\"Slider\"/>" +
          "</synth>";
          
          public static void main(String[] args) throws Exception
          {
            InputStream ins = new ByteArrayInputStream(synthXml.getBytes("UTF8"));
            SynthLookAndFeel laf = new SynthLookAndFeel();
            laf.load(ins, SynthSliderTest.class);
            UIManager.setLookAndFeel(laf);
            
            new SynthSliderTest();
          }

          public SynthSliderTest()
          {
            setLayout(new FlowLayout());
            JSlider slider = new JSlider();
            add(slider);
            add(new JLabel("PrefSize: " + slider.getPreferredSize()));
            
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setSize(new Dimension(400, 300));
            setLocationRelativeTo(null);
            setVisible(true);
          }
        }
        ---------- END SOURCE ----------

        Attachments

          Issue Links

            Activity

              People

                ssadetsky Semyon Sadetsky (Inactive)
                webbuggrp Webbug Group
                Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: