
com.jidesoft.swing.JideScrollPane Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jide-oss Show documentation
Show all versions of jide-oss Show documentation
JIDE Common Layer (Professional Swing Components)
/*
* @(#)JideScrollPane.java
*
* Copyright 2002 - 2005 JIDE Software Inc. All rights reserved.
*/
package com.jidesoft.swing;
import javax.swing.*;
import java.awt.*;
/**
* JideScrollPane
is an enhanced version of JScrollPane
. In JScrollPane
, you can
* have rowHeader and columnHeader. However you can't have rowFooter and columnFooter. However rowFooter and
* columnFooter are very useful in table. For example they can be used to display "total" or "summary" type of
* information.
*
* Several methods related to rowFooter and columnFooter are added such as {@link #setRowFooter(javax.swing.JViewport)},
* and {@link #setColumnFooter(javax.swing.JViewport)} which will set the viewport to rowFooter and columnFooter area
* respectively. The usage of those methods are exactly the same as {@link JScrollPane#setRowHeader(javax.swing.JViewport)}.
*
* To fully leverage the power of JideScrollPane, we also create a class called TableScrollPane
which is
* part of JIDE Grids package. It will allow you to easily create table with row header, row footer and column footer.
* JideScrollPane
also provides support for scrollbar corners. You can set them using {@link
* #setScrollBarCorner(String,java.awt.Component)}. Available key for scroll bar corner is defined at {@link
* JideScrollPaneConstants} which can be access from JideScrollPane
.
*
* Credit: This implementation of scroll bar corner is based on work from Santhosh Kumar -
* [email protected].
*/
public class JideScrollPane extends JScrollPane implements JideScrollPaneConstants {
/**
* The row footer child. Default is null
.
*
* @see #setRowFooter
*/
protected JViewport _rowFooter;
/**
* The column footer child. Default is null
.
*
* @see #setColumnFooter
*/
protected JViewport _columnFooter;
/**
* The component to the left of horizontal scroll bar.
*/
protected Component _hLeft;
/**
* The component to the right of horizontal scroll bar.
*/
protected Component _hRight;
/**
* The component to the top of vertical scroll bar.
*/
protected Component _vTop;
/**
* The component to the bottom of vertical scroll bar.
*/
protected Component _vBottom;
private boolean _horizontalScrollBarCoversWholeWidth;
private boolean _verticalScrollBarCoversWholeHeight;
public static final String PROPERTY_HORIZONTAL_SCROLL_BAR_COVERS_WHOLE_WIDTH = "horizontalScrollBarCoversWholeWidth";
public static final String PROPERTY_VERTICAL_SCROLL_BAR_COVERS_WHOLE_HEIGHT = "verticalScrollBarCoversWholeHeight";
private boolean _columnHeadersHeightUnified;
private boolean _columnFootersHeightUnified;
public static final String PROPERTY_COLUMN_HEADERS_HEIGHT_UNIFIED = "columnHeadersHeightUnified";
public static final String PROPERTY_COLUMN_FOOTERS_HEIGHT_UNIFIED = "columnFootersHeightUnified";
/**
* Creates a JideScrollPane
that displays the view component in a viewport whose view position can be
* controlled with a pair of scrollbars. The scrollbar policies specify when the scrollbars are displayed, For
* example, if vsbPolicy
is VERTICAL_SCROLLBAR_AS_NEEDED
then the vertical scrollbar only
* appears if the view doesn't fit vertically. The available policy settings are listed at {@link
* #setVerticalScrollBarPolicy} and {@link #setHorizontalScrollBarPolicy}.
*
* @param view the component to display in the scrollpanes viewport
* @param vsbPolicy an integer that specifies the vertical scrollbar policy
* @param hsbPolicy an integer that specifies the horizontal scrollbar policy
* @see #setViewportView
*/
public JideScrollPane(Component view, int vsbPolicy, int hsbPolicy) {
setLayout(new JideScrollPaneLayout.UIResource());
setVerticalScrollBarPolicy(vsbPolicy);
setHorizontalScrollBarPolicy(hsbPolicy);
setViewport(createViewport());
setVerticalScrollBar(createVerticalScrollBar());
setHorizontalScrollBar(createHorizontalScrollBar());
if (null != view) {
setViewportView(view);
}
setOpaque(true);
updateUI();
if (!getComponentOrientation().isLeftToRight()) {
viewport.setViewPosition(new Point(Integer.MAX_VALUE, 0));
}
}
/**
* Creates a JideScrollPane
that displays the contents of the specified component, where both
* horizontal and vertical scrollbars appear whenever the component's contents are larger than the view.
*
* @param view the component to display in the scrollpane's viewport
* @see #setViewportView
*/
public JideScrollPane(Component view) {
this(view, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
/**
* Creates an empty (no viewport view) JideScrollPane
with specified scrollbar policies. The available
* policy settings are listed at {@link #setVerticalScrollBarPolicy} and {@link #setHorizontalScrollBarPolicy}.
*
* @param vsbPolicy an integer that specifies the vertical scrollbar policy
* @param hsbPolicy an integer that specifies the horizontal scrollbar policy
* @see #setViewportView
*/
public JideScrollPane(int vsbPolicy, int hsbPolicy) {
this(null, vsbPolicy, hsbPolicy);
}
/**
* Creates an empty (no viewport view) JideScrollPane
where both horizontal and vertical scrollbars
* appear when needed.
*/
public JideScrollPane() {
this(null, VERTICAL_SCROLLBAR_AS_NEEDED, HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
/**
* Returns the row footer.
*
* @return the rowFooter
property
* @see #setRowFooter
*/
public JViewport getRowFooter() {
return _rowFooter;
}
/**
* Removes the old rowFooter, if it exists. If the new rowFooter isn't null
, syncs the y coordinate of
* its viewPosition with the viewport (if there is one) and then adds it to the scrollpane.
*
* @param rowFooter the new row footer to be used; if null
the old row footer is still removed and the
* new rowFooter is set to null
* @see #getRowFooter
* @see #setRowFooterView
*/
public void setRowFooter(JViewport rowFooter) {
JViewport old = getRowFooter();
_rowFooter = rowFooter;
if (null != rowFooter) {
add(rowFooter, ROW_FOOTER);
}
else if (null != old) {
remove(old);
}
firePropertyChange("rowFooter", old, rowFooter);
revalidate();
repaint();
JideSwingUtilities.synchronizeView(rowFooter, getViewport(), SwingConstants.VERTICAL);
JideSwingUtilities.synchronizeView(getViewport(), rowFooter, SwingConstants.VERTICAL);
}
/**
* Overwride setRowHeader method in JScrollPane and synchronize the view with the main viewport. Swing tried to
* implement this feature but it will break if the view position changes starts from rowHeader.
*
* @param rowHeader the new row header
*/
@Override
public void setRowHeader(JViewport rowHeader) {
super.setRowHeader(rowHeader);
JideSwingUtilities.synchronizeView(rowHeader, getViewport(), SwingConstants.VERTICAL);
}
/**
* Creates a row-footer viewport if necessary, sets its view and then adds the row-footer viewport to the
* scrollpane. For example:
*
* JScrollPane scrollpane = new JideScrollPane();
* scrollpane.setViewportView(myBigComponentToScroll);
* scrollpane.setRowFooterView(myBigComponentsRowFooter);
*
*
* @param view the component to display as the row footer
* @see #setRowFooter
* @see JViewport#setView
*/
public void setRowFooterView(Component view) {
if (null == getRowFooter()) {
setRowFooter(createViewport());
}
getRowFooter().setView(view);
}
/**
* Returns the column footer.
*
* @return the columnFooter
property
* @see #setColumnFooter
*/
public JViewport getColumnFooter() {
return _columnFooter;
}
/**
* Removes the old columnFooter, if it exists. If the new columnFooter isn't null
, sync the x
* coordinate of the its viewPosition with the viewport (if there is one) and then add it to the scrollpane.
*
* @param columnFooter the new column footer to be used; if null
the old column footer is still removed
* and the new columnFooter is set to null
* @see #getColumnFooter
* @see #setColumnFooterView
*/
public void setColumnFooter(JViewport columnFooter) {
JViewport old = getColumnFooter();
_columnFooter = columnFooter;
if (null != columnFooter) {
add(columnFooter, COLUMN_FOOTER);
}
else if (null != old) {
remove(old);
}
firePropertyChange("columnFooter", old, columnFooter);
revalidate();
repaint();
JideSwingUtilities.synchronizeView(_columnFooter, getViewport(), SwingConstants.HORIZONTAL);
JideSwingUtilities.synchronizeView(getViewport(), _columnFooter, SwingConstants.HORIZONTAL);
}
/**
* Overrides to make column header viewport synchronizing with the main viewport.
*
* @param columnHeader
*/
@Override
public void setColumnHeader(JViewport columnHeader) {
super.setColumnHeader(columnHeader);
JideSwingUtilities.synchronizeView(this.columnHeader, getViewport(), SwingConstants.HORIZONTAL);
}
/**
* Creates a column-footer viewport if necessary, sets its view, and then adds the column-footer viewport to the
* scrollpane. For example:
*
* JScrollPane scrollpane = new JideScrollPane();
* scrollpane.setViewportView(myBigComponentToScroll);
* scrollpane.setColumnFooterView(myBigComponentsColumnFooter);
*
*
* @param view the component to display as the column footer
* @see #setColumnFooter
* @see JViewport#setView
*/
public void setColumnFooterView(Component view) {
if (null == getColumnFooter()) {
setColumnFooter(createViewport());
}
getColumnFooter().setView(view);
}
/**
* Returns the component at the specified scroll bar corner. The key
value specifying the corner is one
* of: - {@link JideScrollPane#HORIZONTAL_LEFT}
- {@link JideScrollPane#HORIZONTAL_RIGHT}
- {@link
* JideScrollPane#VERTICAL_TOP}
- {@link JideScrollPane#VERTICAL_BOTTOM}
- {@link
* JideScrollPane#HORIZONTAL_LEADING}
- {@link JideScrollPane#HORIZONTAL_TRAILING}
*
* @param key one of the values as shown above
* @return one of the components listed below or null
if key
is invalid:
* - lowerLeft
- lowerRight
- upperLeft
- upperRight
* @see #setCorner
*/
public Component getScrollBarCorner(String key) {
boolean isLeftToRight = getComponentOrientation().isLeftToRight();
if (key.equals(HORIZONTAL_LEADING)) {
key = isLeftToRight ? HORIZONTAL_LEFT : HORIZONTAL_RIGHT;
}
else if (key.equals(HORIZONTAL_TRAILING)) {
key = isLeftToRight ? HORIZONTAL_RIGHT : HORIZONTAL_LEFT;
}
if (key.equals(HORIZONTAL_LEFT)) {
return _hLeft;
}
else if (key.equals(HORIZONTAL_RIGHT)) {
return _hRight;
}
else if (key.equals(VERTICAL_BOTTOM)) {
return _vBottom;
}
else if (key.equals(VERTICAL_TOP)) {
return _vTop;
}
else {
return null;
}
}
/**
* Adds a child that will appear in one of the scroll bars corners. Scroll bar will make room to show the corner
* component. Legal values for the key are: - {@link JideScrollPane#HORIZONTAL_LEFT}
- {@link
* JideScrollPane#HORIZONTAL_RIGHT}
- {@link JideScrollPane#VERTICAL_TOP}
- {@link
* JideScrollPane#VERTICAL_BOTTOM}
- {@link JideScrollPane#HORIZONTAL_LEADING}
- {@link
* JideScrollPane#HORIZONTAL_TRAILING}
*
* Although "corner" doesn't match any beans property signature, PropertyChange
events are generated
* with the property name set to the corner key.
*
* @param key identifies which corner the component will appear in
* @param corner one of the following components: - lowerLeft
- lowerRight
- upperLeft
- upperRight
*
* @throws IllegalArgumentException if corner key is invalid
*/
public void setScrollBarCorner(String key, Component corner) {
Component old;
boolean isLeftToRight = getComponentOrientation().isLeftToRight();
if (key.equals(HORIZONTAL_LEADING)) {
key = isLeftToRight ? HORIZONTAL_LEFT : HORIZONTAL_RIGHT;
}
else if (key.equals(HORIZONTAL_TRAILING)) {
key = isLeftToRight ? HORIZONTAL_RIGHT : HORIZONTAL_LEFT;
}
if (key.equals(HORIZONTAL_LEFT)) {
old = _hLeft;
_hLeft = corner;
}
else if (key.equals(HORIZONTAL_RIGHT)) {
old = _hRight;
_hRight = corner;
}
else if (key.equals(VERTICAL_TOP)) {
old = _vTop;
_vTop = corner;
}
else if (key.equals(VERTICAL_BOTTOM)) {
old = _vBottom;
_vBottom = corner;
}
else {
throw new IllegalArgumentException("invalid scroll bar corner key");
}
if (null != old) {
remove(old);
}
if (null != corner) {
add(corner, key);
}
if (corner != null) corner.setComponentOrientation(getComponentOrientation());
firePropertyChange(key, old, corner);
revalidate();
repaint();
}
@Override
public void updateUI() {
super.updateUI();
setLayout(new JideScrollPaneLayout.UIResource());
LookAndFeel.installBorder(this, "JideScrollPane.border");
}
public boolean isVerticalScrollBarCoversWholeHeight() {
return _verticalScrollBarCoversWholeHeight;
}
public void setHorizontalScrollBarCoversWholeWidth(boolean horizontalScrollBarCoversWholeWidth) {
boolean old = _horizontalScrollBarCoversWholeWidth;
if (old != horizontalScrollBarCoversWholeWidth) {
_horizontalScrollBarCoversWholeWidth = horizontalScrollBarCoversWholeWidth;
firePropertyChange(PROPERTY_HORIZONTAL_SCROLL_BAR_COVERS_WHOLE_WIDTH, old, _horizontalScrollBarCoversWholeWidth);
invalidate();
doLayout();
if (getHorizontalScrollBar() != null) {
getHorizontalScrollBar().doLayout();
}
}
}
public boolean isHorizontalScrollBarCoversWholeWidth() {
return _horizontalScrollBarCoversWholeWidth;
}
public void setVerticalScrollBarCoversWholeHeight(boolean verticalScrollBarCoversWholeHeight) {
boolean old = _verticalScrollBarCoversWholeHeight;
if (old != verticalScrollBarCoversWholeHeight) {
_verticalScrollBarCoversWholeHeight = verticalScrollBarCoversWholeHeight;
firePropertyChange(PROPERTY_VERTICAL_SCROLL_BAR_COVERS_WHOLE_HEIGHT, old, _verticalScrollBarCoversWholeHeight);
invalidate();
doLayout();
if (getVerticalScrollBar() != null) {
getVerticalScrollBar().doLayout();
}
}
}
/**
* If true, the top-right, top-left corners the column header will have the same height. If false, three of them
* will keep their own preferred height.
*
* @return true or false.
*/
public boolean isColumnHeadersHeightUnified() {
return _columnHeadersHeightUnified;
}
/**
* Sets the flag if the top-right, top-left corner and the column header will have the same height or different
* heights.
*
* @param columnHeadersHeightUnified true or false.
*/
public void setColumnHeadersHeightUnified(boolean columnHeadersHeightUnified) {
boolean old = _columnHeadersHeightUnified;
if (old != columnHeadersHeightUnified) {
_columnHeadersHeightUnified = columnHeadersHeightUnified;
firePropertyChange(PROPERTY_COLUMN_HEADERS_HEIGHT_UNIFIED, old, _horizontalScrollBarCoversWholeWidth);
invalidate();
doLayout();
}
}
/**
* If true, the bottom-right, bottom-left corners the column footer will have the same height. If false, three of
* them will keep their own preferred height.
*
* @return true or false.
*/
public boolean isColumnFootersHeightUnified() {
return _columnFootersHeightUnified;
}
/**
* Sets the flag if the bottom-right, bottom-left corner and the column footer will have the same height or
* different heights.
*
* @param columnFootersHeightUnified true or false.
*/
public void setColumnFootersHeightUnified(boolean columnFootersHeightUnified) {
boolean old = _columnFootersHeightUnified;
if (old != columnFootersHeightUnified) {
_columnFootersHeightUnified = columnFootersHeightUnified;
firePropertyChange(PROPERTY_COLUMN_FOOTERS_HEIGHT_UNIFIED, old, _horizontalScrollBarCoversWholeWidth);
invalidate();
doLayout();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy