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

ScrollPane.setScrollPosition does not vertically scroll content inside JPanel

    XMLWordPrintable

    Details

    • Subcomponent:
    • CPU:
      x86
    • OS:
      linux

      Description

      FULL PRODUCT VERSION :
      java version "1.4.2_13"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_13-b06)
      Java HotSpot(TM) Client VM (build 1.4.2_13-b06, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      Linux 2.4.21-47.ELsmp #1 SMP Wed Jul 5 20:38:41 EDT 2006 i686 i686 i386 GNU/Linux

      A DESCRIPTION OF THE PROBLEM :
      ScrollPane.setScrollPosition does not vertically scroll the content area of a JPanel that contains sub-components (eg. JTextArea or JLabel) under JDK 1.4.2 under Linux. Note that this works under JDK 1.5+ and JDK 1.4.2 under Windows.

      under Linux and JDK 1.4.2, when the setScrollPosition(..) is called with any "y" values, it scrolls the scroll bar to the correct position, but the content area is always scrolled to the top.

      See sample test cases

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      see attached test case.

      essentially, when we have a JPanel that contains other objects (eg. JTextArea, or JLabel) with some type of Layout (eg. GridLayout or SpringLayout), inside a ScrollPane, the ScrollPane.setScrollPosition does not set the correct vertical (eg. y-axis) of the content.

      this problem seems to only affect JDK 1.4.2 under Linux

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      the scroll bar should be moved to the bottom and the content area should be vertically scrolled to the bottom (to display the line of the content)
      ACTUAL -
      the scroll bar is moved to the bottom, but the content area jumps to the top

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      /*
       * test case 1 using JTextArea
       * ScrollPaneimpleTest.java is a 1.4 example that requires no other files.
       * This simple test application will test the programatical vertical
       * scrolling function of ScrollPane via ScrollPane.setScrollPosition(..)
       * This works on JDK 1.5+ and 1.4.2 on Windows, but on Linux under JDK 1.4.2_13
       * pressing the "bottom" button does not scroll the content view to the botttom,
       * it does scroll the scrollbar to the bottom. This seems to be a defect in
       * Java 1.4.2 on linux. For some reason, setScrollPosition(..) work for scrolling
       * to the top under all platforms.
       */
      import java.awt.*;
      import java.awt.event.*;

      import javax.swing.*;

      public class ScrollPaneSimpleTest implements ActionListener {
        JButton bottomButton;
        JButton topButton;
        ScrollPane scrollPane;
        JPanel panel;

        public Component createComponents() {
          // create buttons
          bottomButton = new JButton("Bottom");
          bottomButton.addActionListener(this);
          bottomButton.setToolTipText("You should see the last line of text at the bottom after clicking on this");
          topButton = new JButton("Top");
          topButton.addActionListener(this);
          topButton.setToolTipText("You should see the first line of text at the top after clicking on this");

          // create JPanel to put into ScrollPane
          panel = new JPanel(new GridLayout(1, 1));

          // some text data for the content panel that would be big enough
          // to require a vertical scroll bar for the scrollPane
          StringBuffer sb = new StringBuffer(256);
          sb.append("--- this is the first line of text ---");
          for (int i=0; i<100; i++) {
            sb.append("\nthis is line " + i);
          }
          sb.append("\n--- this is the last line ---");
          
          // create JTextArea to put inside JPanel
          JTextArea textArea = new JTextArea(sb.toString());
          textArea.setEditable(false);
          Dimension contentDim = textArea.getPreferredSize();
          textArea.setSize(contentDim);
          
          panel.setPreferredSize(contentDim);
          panel.setSize(contentDim);
          panel.add(textArea);

          // create scroll pane
          scrollPane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
          // set a size that will require vertical scrolling for the scroll pane
          scrollPane.setSize(300, 200);
          // add JPanel to scroll pane
          scrollPane.add(panel);

          return scrollPane;
        }

        /**
         * When user clicks on either the "Top" or "Bottom" button, then
         * try to vertically scroll the content area via the ScrollPane
         */
        public void actionPerformed(ActionEvent e) {
          final Object src = e.getSource();
          if ((src == bottomButton) || (src == topButton)) {
            scrollVertical(e.getActionCommand());
          }
        }

        /**
         * Scroll to the specified vertical (bottom, top) position in the scroll panel.
         *
         * @param vpos "Top" for for scrolling to top, everything else defaults to
         * scrolling to the bottom.
         */
        private void scrollVertical(String vpos) {
          int x = 0;
          int h = panel.getHeight(); // get panel's height so that we scroll to bottom

          if ("TOP".equalsIgnoreCase(vpos)) {
            scrollPane.setScrollPosition(x, 0);
          } else { // defaults to bottom
            scrollPane.setScrollPosition(x, h);
          }

          panel.validate();
          panel.repaint();
          scrollPane.repaint();
        }

        /**
         * Create the GUI and show it. For thread safety, this method should be
         * invoked from the event-dispatching thread.
         */
        private static void createAndShowGUI() {
          // Make sure we have nice window decorations.
          JFrame.setDefaultLookAndFeelDecorated(true);

          // Create and set up the window.
          JFrame frame = new JFrame("ScrollPane test");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          
          frame.setLocation(400, 100);

          // create application and its components
          ScrollPaneSimpleTest app = new ScrollPaneSimpleTest();
          Component component = app.createComponents();

          // add application components to frame
          frame.getContentPane().add(component);
          frame.getContentPane().add(app.topButton, BorderLayout.PAGE_START);
          frame.getContentPane().add(app.bottomButton, BorderLayout.PAGE_END);

          // Display the window.
          frame.pack();
          frame.setVisible(true);
        }

        public static void main(String[] args) {
          // Schedule a job for the event-dispatching thread:
          // creating and showing this application's GUI.
          javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
              createAndShowGUI();
            }
          });
        }
      }


      ----- test case 2 using JLabel ---
      /*
       * test case 2 using JLabel (you will need the update code to reference appropriate
       * image (currently sunset.jpg) that is on your system (please choose an image that
       * is larger the than 300x200 which is the hard-coded size of the ScrollPane.
       *
       * ScrollPaneimpleTest2.java is a 1.4 example that requires no other files.
       * This simple test application will test the programatical vertical
       * scrolling function of ScrollPane via ScrollPane.setScrollPosition(..)
       * This works on JDK 1.5+ and 1.4.2 on Windows, but on Linux under JDK 1.4.2_13
       * pressing the "bottom" button does not scroll the content view to the botttom,
       * it does scroll the scrollbar to the bottom. This seems to be a defect in
       * Java 1.4.2 on linux. For some reason, setScrollPosition(..) work for scrolling
       * to the top under all platforms.
       */
      import java.awt.*;
      import java.awt.event.*;

      import javax.swing.*;

      public class ScrollPaneSimpleTest2 implements ActionListener {
        JButton bottomButton;
        JButton topButton;
        ScrollPane scrollPane;
        JPanel panel;

        public Component createComponents() {
          // create buttons
          bottomButton = new JButton("Bottom");
          bottomButton.addActionListener(this);
          bottomButton.setToolTipText("You should see the last line of text at the bottom after clicking on this");
          topButton = new JButton("Top");
          topButton.addActionListener(this);
          topButton.setToolTipText("You should see the first line of text at the top after clicking on this");

          // create JPanel to put into ScrollPane
          panel = new JPanel(new GridLayout(1, 1));

          // create JLabel to put inside JPanel
          ImageIcon image = new ImageIcon("Sunset.jpg", "sunset");
          JLabel label = new JLabel(image);
          Dimension contentDim = label.getPreferredSize();
          
          panel.setPreferredSize(contentDim);
          panel.setSize(contentDim);
          panel.add(label);

          // create scroll pane
          scrollPane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
          // set a size that will require vertical scrolling for the scroll pane
          scrollPane.setSize(300, 200);
          // add JPanel to scroll pane
          scrollPane.add(panel);

          return scrollPane;
        }

        /**
         * When user clicks on either the "Top" or "Bottom" button, then
         * try to vertically scroll the content area via the ScrollPane
         */
        public void actionPerformed(ActionEvent e) {
          final Object src = e.getSource();
          if ((src == bottomButton) || (src == topButton)) {
            scrollVertical(e.getActionCommand());
          }
        }

        /**
         * Scroll to the specified vertical (bottom, top) position in the scroll panel.
         *
         * @param vpos "Top" for for scrolling to top, everything else defaults to
         * scrolling to the bottom.
         */
        private void scrollVertical(String vpos) {
          int x = 0;
          int h = panel.getHeight(); // get panel's height so that we scroll to bottom

          if ("TOP".equalsIgnoreCase(vpos)) {
            scrollPane.setScrollPosition(x, 0);
          } else { // defaults to bottom
            scrollPane.setScrollPosition(x, h);
          }

          panel.validate();
          panel.repaint();
          scrollPane.repaint();
        }

        /**
         * Create the GUI and show it. For thread safety, this method should be
         * invoked from the event-dispatching thread.
         */
        private static void createAndShowGUI() {
          // Make sure we have nice window decorations.
          JFrame.setDefaultLookAndFeelDecorated(true);

          // Create and set up the window.
          JFrame frame = new JFrame("ScrollPane test");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          
          frame.setLocation(400, 100);

          // create application and its components
          ScrollPaneSimpleTest2 app = new ScrollPaneSimpleTest2();
          Component component = app.createComponents();

          // add application components to frame
          frame.getContentPane().add(component);
          frame.getContentPane().add(app.topButton, BorderLayout.PAGE_START);
          frame.getContentPane().add(app.bottomButton, BorderLayout.PAGE_END);

          // Display the window.
          frame.pack();
          frame.setVisible(true);
        }

        public static void main(String[] args) {
          // Schedule a job for the event-dispatching thread:
          // creating and showing this application's GUI.
          javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
              createAndShowGUI();
            }
          });
        }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      use JDK 1.5+
      or use JDK 1.4.2 under Windows

        Attachments

          Activity

            People

            Assignee:
            Unassigned Unassigned
            Reporter:
            dav Andrei Dmitriev (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: