Posted by Rob Camick on December 20, 2009
When using a JScrollPane the general rule is that the scrollbars will appear when the “preferred size” of the component added to the JViewport of the scroll pane is greater than the “size” of the viewport. There may be times when you wish to prevent a scrollbar from appearing even though the preferred size is greater than the size.
To prevent the horizontal scrollbar from appearing the first solution you might attempt would be to use the setHorizontalScrollBarPolicy() method of JScrollPane with a value of ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER. This works, in the sense that the scrollbar is not displayed, but the problem is that the view of the component is just truncated in the viewport.
A more flexible approach is to implement the Scrollable interface on your component. In this solution you would want to override the getScrollableTracksViewportWidth() method to return “true”. The width of the component is now set to be the width of the viewport (instead of the preferred width of the component). This can affect the way the layout of the component is done (in the case of using a JPanel) or it can affect the way a component is painted (in the case of a JTextArea using wrapping). However, the Scrollable interface specifies 5 different methods and since many components don’t implement this interface you will usually end up implementing all 5 methods.
The purpose of the ScrollablePanel class is to provide reasonable implementations for each of the Scrollable methods and to support easy customization of the Scrollable behaviour.
The Scrollable interface only provides a boolean value for determining whether or not the viewport size (width or height) should be used by the scrollpane when determining if scrollbars should be made visible. ScrollablePanel supports this as well as adding the concept of dynamically changing this value based on the size of the viewport. In this case the viewport size will only be used when it is larger than the panels size. This has the effect of ensuring the viewport is always full as components added to the panel will be sized to fill the area available, based on the rules of the applicable layout manager of course.
The Scrollable interface also allows you to control the scroll amount for the horizontal and vertical scrollbars at the “unit” or “block” level. Using the ScrollablePanel, you can specify scroll amounts as a percentage of the viewport size or as an actual pixel value.
The methods added to implement this support are:
- setScrollableHeight – The valid values for this method are:
- ScrollableSizeHint.NONE (default) – the panel will be displayed in the viewport at its preferred size and therefore all the components will be layed out at their preferred sizes as well. Scrollbars may or may not appear.
- ScrollableSizeHint.FIT – the panel and its components will attempt to be resized to fit completely in the viewport. This may result in the components shrinking or stretching. It also allows for the possibility that the panel will be truncated if the components cannot be shrunk enough to fit in the viewport. Scrollbars will never appear.
- ScrollableSizeHint.STRETCH – the panel and its components will generally be displayed at their preferred sizes. However, it is possible that they may be stretched in order to completely fill the viewport. Scrollbars may or may not appear.
- setScrollableWidth – See above for the valid values.
- setScrollableBlockIncrement -
- The “orientation” must be one of HORIZONTAL or VERTICAL.
- The “increment type” must be one of IncrementType.PERCENT or IncrementType.PIXEL.
- setScrollableUnitIncrement – See above for valid values.
As a simple example you might have a ScrollablePanel without a horizontal scrollbar that has a vertical block scroll of 200 percent:
ScrollablePanel panel = new ScrollablePanel(...);
panel.setScrollableWidth( ScrollablePanel.ScrollableSizeHint.FIT );
ScrollablePanel.VERTICAL, ScrollablePanel.IncrementType.PERCENT, 200);
JScrollPane scrollPane = new JScrollPane( panel );
The WebStart demo uses a panel with buttons using a GridLayout. This was choosen because the GridLayout will resize compnents to fill the space available. Try the different values and don’t forget to resize the frame to so how the scrollbars react with the various options. Different layout managers will have different effects.