All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jidesoft.swing.JideScrollPane Maven / Gradle / Ivy

/*
 * @(#)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"; /** * 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); } /** * 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); } /** * Overrides to make column header viewport synchonizing 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); } firePropertyChange(key, old, corner); revalidate(); repaint(); } @Override public void updateUI() { super.updateUI(); LookAndFeel.installBorder(this, "JideScrollPane.border"); } public boolean isVerticalScrollBarCoversWholeHeight() { return _verticalScrollBarCoversWholeHeight; } public boolean isHorizontalScrollBarCoversWholeWidth() { return _horizontalScrollBarCoversWholeWidth; } 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 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(); } } } @Override protected JViewport createViewport() { return new JViewport() { @Override public Dimension getViewSize() { Dimension viewSize = super.getViewSize(); if (getView() == JideScrollPane.this.getViewport().getView()) { if (rowHeader != null) { Dimension headerSize = rowHeader.getViewSize(); if (viewSize.height < headerSize.height) { viewSize.height = headerSize.height; } } else if (columnHeader != null) { Dimension headerSize = columnHeader.getViewSize(); if (viewSize.width < headerSize.width) { viewSize.width = headerSize.width; } } } return viewSize; } }; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy