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

JViewport's Component listener results in 2 times the amount of layouts needed

    XMLWordPrintable

Details

    Description

      FULL PRODUCT VERSION :
      Java(TM) SE Runtime Environment (build 1.6.0-rc-b95)


      A DESCRIPTION OF THE PROBLEM :
      JViewport listens to changes in its size and revalidates when a change occurs:
          protected class ViewListener extends ComponentAdapter implements Serializable
          {
              public void componentResized(ComponentEvent e) {
                  fireStateChanged();
                  revalidate();
              }
          }

      This is good but when used in combination with a JScrollPane/ScrollPaneLayout it can result in double the amount of layouts needed. The ScrollPaneLayout will set the bounds of the view. If this results in a change to the size, the component listener is notified. When notified it revalidates itself, which means the RepaintManager looks for the validation root. If its the JScrollPane this means everything gets layed out again when there needs to be only one layout. This probably doesn't help performance.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run this test, click the "Change Size" button and see how many times the ScrollPaneLayout lays out in response to the change in size.
      import javax.swing.*;
      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.table.*;

      public class TestViewport implements Runnable{


          public class JScrollPane2 extends JScrollPane{
              int layoutcount = 0;

              public JScrollPane2(JComponent view){
      super(view);
                  setLayout(new ScrollPaneLayout2());
              }

              @Override
              public void doLayout(){
                  System.out.println("LAYOUT: " + (++layoutcount));
                  super.doLayout();
              }

              class ScrollPaneLayout2 extends ScrollPaneLayout{
                  int count = 0;
                  public void layoutContainer(Container parent){
                      System.out.println("SCPLAYOUT2 COUNT: " + (++count));
                      super.layoutContainer(parent);
                  }

              }



          }


          public void run(){
              Object[][] data = new Object[10][10];
              Object[] names = new Object[10];
              for(int i = 0; i < 10; i++){
      names[i] = String.valueOf(i);
                  for(int j = 0; j < 10; j++)
      data[i][j] = String.valueOf(j);

              }

              JTable jt = new JTable(data, names);
              JScrollPane2 jsp = new JScrollPane2(jt);
              final JFrame jf = new JFrame();
              jf.add(jsp);
              jf.pack();
              jf.setVisible(true);
              JButton sizechange = new JButton("Change Size"){
                      @Override
      public void fireActionPerformed(ActionEvent e){
      Dimension size = jf.getSize();
                          size.width += 1;
                          jf.setSize(size);
                      }
      };
      jf.add(sizechange, BorderLayout.SOUTH);
          }


          public static void main(String ... args){
      SwingUtilities.invokeLater(new TestViewport());
          }

      }

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      That there will only be one layout, not 2.
      ACTUAL -
      there are at least 2 layouts

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import javax.swing.*;
      import java.awt.*;
      import java.awt.event.*;
      import javax.swing.table.*;

      public class TestViewport implements Runnable{


          public class JScrollPane2 extends JScrollPane{
              int layoutcount = 0;

              public JScrollPane2(JComponent view){
      super(view);
                  setLayout(new ScrollPaneLayout2());
              }

              @Override
              public void doLayout(){
                  System.out.println("LAYOUT: " + (++layoutcount));
                  super.doLayout();
              }

              class ScrollPaneLayout2 extends ScrollPaneLayout{
                  int count = 0;
                  public void layoutContainer(Container parent){
                      System.out.println("SCPLAYOUT2 COUNT: " + (++count));
                      super.layoutContainer(parent);
                  }

              }



          }


          public void run(){
              Object[][] data = new Object[10][10];
              Object[] names = new Object[10];
              for(int i = 0; i < 10; i++){
      names[i] = String.valueOf(i);
                  for(int j = 0; j < 10; j++)
      data[i][j] = String.valueOf(j);

              }

              JTable jt = new JTable(data, names);
              JScrollPane2 jsp = new JScrollPane2(jt);
              final JFrame jf = new JFrame();
              jf.add(jsp);
              jf.pack();
              jf.setVisible(true);
              JButton sizechange = new JButton("Change Size"){
                      @Override
      public void fireActionPerformed(ActionEvent e){
      Dimension size = jf.getSize();
                          size.width += 1;
                          jf.setSize(size);
                      }
      };
      jf.add(sizechange, BorderLayout.SOUTH);
          }


          public static void main(String ... args){
      SwingUtilities.invokeLater(new TestViewport());
          }

      }
      ---------- END SOURCE ----------

      Attachments

        Activity

          People

            Unassigned Unassigned
            rmandalasunw Ranjith Mandala (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Imported:
              Indexed: