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

JSplitPane has poor default layout when containing a JScrollPane

    XMLWordPrintable

Details

    Description

      FULL PRODUCT VERSION :
      1.4.2_09

      A DESCRIPTION OF THE PROBLEM :
      Consider a split pane with a vertical split (as used in the source code below). In the top is a JScrollPane which contains a large component (in this case a JTextArea with 100 lines of text), in the bottom is a small component (in this case a JLabel).

      When the JSplitPane is first displayed and insufficient space is available to fully display both top and bottom components at their preferred sizes, the default layout manager (BasicSplitPaneUI$BasicHorizontalLayoutManager) opts to ignore the preferred sizes and use the minimum sizes as a starting point (see "resetToPreferredSizes(int availableSize)," line 2049). Note that whilst many components have a minimum size which is similar or equal to their preferred size, JScrollPane has a minimum size which can be a great deal smaller than the preferred size.

      Once it starts from minimum sizes, it then uses the "resize weight" (or, rather, *abuses* it, since no resizing has taken place; this is simply laying out the component) to assign space, the result being that the lower component gets all of the space. No account is taken of the difference between the preferred and minimum sizes of each component. You will notice that if you change the number of lines in the text area, starting from empty, as you add more lines the area grows - as expected - until it reaches the point where it is too large for the split, at which point suddenly it becomes very small. This is discontinuous and semantically dubious behaviour.

      Suggest that instead of starting at the minimum sizes, "resetToPreferredSizes" should always take the preferred sizes as a starting point and should *trim* space from the child components (according to the resize weight?) *until* it hits the child components' minimum sizes or fits the available space.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the attached source code.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      The split should appear with the JLabel in the lower half being allocated no more space than its preferred size.
      ACTUAL -
      The split appears with the JLabel in the lower half being allocated nearly all of the available space.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.BorderLayout;
      import java.awt.Dimension;

      import javax.swing.JComponent;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.JPanel;
      import javax.swing.JScrollPane;
      import javax.swing.JSplitPane;
      import javax.swing.JTextArea;
      import javax.swing.SwingUtilities;

      public class SplitPaneBug implements Runnable
      {
      public static final void main(String[] args)
      {
      SwingUtilities.invokeLater(new SplitPaneBug());
      }

      public void run()
      {
      JTextArea textArea = new JTextArea();
      for (int i = 0; i < 100; i ++)
      {
      if (i > 0)
      {
      textArea.append("\n");
      }
      textArea.append("Line " + (i + 1));
      }
      JScrollPane scroll = new JScrollPane(textArea);

      JLabel label = new JLabel("", JLabel.CENTER);

      JSplitPane split = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
      split.setTopComponent(scroll);
      split.setBottomComponent(label);

      JComponent content = new JPanel(new BorderLayout());
      content.add(split, BorderLayout.CENTER);

      JFrame f = new JFrame();
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.setContentPane(content);
      f.pack();
      f.setSize(new Dimension(600, 600));
      f.setLocationRelativeTo(null);
      f.setVisible(true);

      label.setText("The split pane layout gives this label " + (label.getSize().height - label.getPreferredSize().height) + "px of height it doesn't need.");
      }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      None found - the relevant classes (BasicSplitPaneUI, BasicHorizontalLayoutManager) make heavy use of package protection which prevents an easy workaround (eg the layout manager uses package protected constructors and hence cannot be extended).

      Attachments

        Activity

          People

            Unassigned Unassigned
            ndcosta Nelson Dcosta (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Imported:
              Indexed: