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

Method BasicScrollPaneUI.ScrollAction.actionPerformed(ActionEvent) works incorre




      Name: kaC94536 Date: 01/27/2000

      Method BasicScrollPaneUI.ScrollAction.actionPerformed(ActionEvent) works incorrectly with keyboard
      events when scroll pane contains not scrollable component.

      Java 2 Platform SE v1.2.2 specification reads:

      public class JScrollPane
      extends JComponent
      implements ScrollPaneConstants, Accessible

      A specialized container that manages a viewport, optional vertical and horizontal scrollbars, and
      optional row and column heading viewports.

      The JViewport provides a window, or "viewport" onto a data source -- for example, a text file. That
      data source is the "scrollable client" (aka data model) displayed by the JViewport view.

      Specification does not state that viewport can display area outside client bounds.

      The following test demonstrates described effect.

      Frame of the test contains JScrollPane component. The scroll panel contains JTextArea component and
      JButton component. If you click on the button, you will see sizes and locations of the scroll panel
      and split panel in standart output device.

      To see described effect try the following:

      1. In the text area press "Enter" for five times. Split panel moves up (text area is not visible now,
      bottom part of frame becomes gray, scrollbar does not appear). Split panel location becomes (0,-34).

      2. In the text area press Tab for 2 times. Split panel moves left. Split panel location becomes (-43,0).

      3. Click on the button, then press PageUp. Split panel moves down.


      import javax.swing.*;
      import java.awt.*;
      import java.awt.event.*;

      public class test extends JFrame implements ActionListener {
          JSplitPane aPane;
          JScrollPane aJScrollPane;

          public test() {
              super("JScrollPane test");
              JButton aButton = new JButton("check");
              aPane=new JSplitPane(JSplitPane.VERTICAL_SPLIT, new JTextArea(), aButton);
              aJScrollPane = new JScrollPane(aPane);

          public void actionPerformed(ActionEvent e) {
              if (e.getActionCommand().equals("check")) {
                  System.out.println("Split panel size " + aPane.getSize());
                  System.out.println("Split panel location " + aPane.getLocation());
                  System.out.println("Scroll panel size " + aJScrollPane.getSize());

          public static void main(String[] args) {
              JFrame frame = new test();
              frame.addWindowListener(new WindowAdapter() {
                  public void windowClosing(WindowEvent e) {


      In my opinion, some additional checks are required in
      BasicScrollPaneUI.ScrollAction.actionPerformed(ActionEvent) method
      (/swing/plaf/basic/BasicScrollPaneUI.java 1.2):

      public void actionPerformed(ActionEvent e) {
          JViewport vp = scrollpane.getViewport();
          Component view;
          if (vp != null && (view = vp.getView()) != null) {
              Rectangle visRect = vp.getViewRect();
              Dimension vSize = view.getSize();
              int amount;
              if (view instanceof Scrollable) {
                  amount = ((Scrollable)view).getScrollableBlockIncrement(visRect, orientation, direction);
              else {
                  if (orientation == SwingConstants.VERTICAL) {
                      amount = visRect.height;
                  else {
                      amount = visRect.width;
              if (orientation == SwingConstants.VERTICAL) {
                  visRect.y += (amount * direction);
                  if ((visRect.y + visRect.height) > vSize.height) {
                      visRect.y = Math.max(0, vSize.height - visRect.height);

              Additional check like this is required here:
                      if (visRect.y <= 0) visRect.y = 0;

              else {
                  visRect.x += (amount * direction);
                  if ((visRect.x + visRect.width) > vSize.width) {
                      visRect.x = Math.max(0, vSize.width - visRect.width);

              Additional check like this is required here:
                      if (visRect.x <= 0) visRect.x = 0;







            sswingtrsunw Swingtraq Swingtraq (Inactive)
            kanisimosunw Konstantin Anisimov (Inactive)
            0 Vote for this issue
            2 Start watching this issue