package javax.swing;
import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
import javax.accessibility.Accessible;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ScrollPaneUI;
import javax.swing.plaf.UIResource;
public class JScrollPane
extends JComponent
implements Accessible, ScrollPaneConstants
{
private static final long serialVersionUID = 5203525440012340014L;
protected JViewport columnHeader;
protected JViewport rowHeader;
protected Component lowerLeft;
protected Component lowerRight;
protected Component upperLeft;
protected Component upperRight;
protected JScrollBar horizontalScrollBar;
protected int horizontalScrollBarPolicy;
protected JScrollBar verticalScrollBar;
protected int verticalScrollBarPolicy;
protected JViewport viewport;
Border viewportBorder;
boolean wheelScrollingEnabled;
ChangeListener scrollListener;
public static final String COLUMN_HEADER_CHANGED_PROPERTY = "columnHeader";
public static final String COMPONENT_ORIENTATION_CHANGED_PROPERTY = "componentOrientation";
public static final String HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY = "horizontalScrollBar";
public static final String HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY = "horizontalScrollBarPolicy";
public static final String LAYOUT_CHANGED_PROPERTY = "layout";
public static final String ROW_HEADER_CHANGED_PROPERTY = "rowHeader";
public static final String VERTICAL_SCROLLBAR_CHANGED_PROPERTY = "verticalScrollBar";
public static final String VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY = "verticalScrollBarPolicy";
public static final String VIEWPORT_CHANGED_PROPERTY = "viewport";
public static final String VIEWPORT_BORDER_CHANGED_PROPERTY = "viewportBorder";
public static final String WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY = "wheelScrollingEnabled";
public JViewport getColumnHeader()
{
return columnHeader;
}
public Component getCorner(String key) {
if (getComponentOrientation()
== ComponentOrientation.LEFT_TO_RIGHT)
{
if (key == LOWER_LEADING_CORNER)
key = LOWER_LEFT_CORNER;
else if (key == LOWER_TRAILING_CORNER)
key = LOWER_RIGHT_CORNER;
else if (key == UPPER_LEADING_CORNER)
key = UPPER_LEFT_CORNER;
else if (key == UPPER_TRAILING_CORNER)
key = UPPER_RIGHT_CORNER;
}
else if (getComponentOrientation()
== ComponentOrientation.RIGHT_TO_LEFT)
{
if (key == LOWER_LEADING_CORNER)
key = LOWER_RIGHT_CORNER;
else if (key == LOWER_TRAILING_CORNER)
key = LOWER_LEFT_CORNER;
else if (key == UPPER_LEADING_CORNER)
key = UPPER_RIGHT_CORNER;
else if (key == UPPER_TRAILING_CORNER)
key = UPPER_LEFT_CORNER;
}
if (key == LOWER_RIGHT_CORNER)
return lowerRight;
else if (key == UPPER_RIGHT_CORNER)
return upperRight;
else if (key == LOWER_LEFT_CORNER)
return lowerLeft;
else if (key == UPPER_LEFT_CORNER)
return upperLeft;
return null;
}
public JScrollBar getHorizontalScrollBar()
{
return horizontalScrollBar;
}
public int getHorizontalScrollBarPolicy()
{
return horizontalScrollBarPolicy;
}
public JViewport getRowHeader()
{
return rowHeader;
}
public JScrollBar getVerticalScrollBar()
{
return verticalScrollBar;
}
public int getVerticalScrollBarPolicy()
{
return verticalScrollBarPolicy;
}
public JViewport getViewport()
{
return viewport;
}
public Border getViewportBorder()
{
return viewportBorder;
}
public Rectangle getViewportBorderBounds()
{
if (viewportBorder == null)
{
if (getViewport() == null)
return new Rectangle(0,0,0,0);
else
return getViewport().getBounds();
}
else
{
Insets i = viewportBorder.getBorderInsets(getViewport());
if (getViewport() == null)
return new Rectangle(0,0,
i.left+i.right, i.top+i.bottom);
else
{
Rectangle b = getViewport().getBounds();
return new Rectangle(b.x - i.left,
b.y - i.top,
b.width + i.left + i.right,
b.height + i.top + i.bottom);
}
}
}
public boolean isWheelScrollingEnabled()
{
return wheelScrollingEnabled;
}
private void sync()
{
LayoutManager m = super.getLayout();
if (m != null && m instanceof ScrollPaneLayout)
{
ScrollPaneLayout sl = (ScrollPaneLayout) m;
sl.syncWithScrollPane(this);
}
}
private void removeNonNull(Component c)
{
if (c != null)
remove(c);
}
private void addNonNull(Component c)
{
if (c != null)
add(c);
}
public void setComponentOrientation(ComponentOrientation co)
{
ComponentOrientation old = super.getComponentOrientation();
super.setComponentOrientation(co);
firePropertyChange(COMPONENT_ORIENTATION_CHANGED_PROPERTY, old, co);
sync();
}
public void setColumnHeader(JViewport h)
{
JViewport old = columnHeader;
removeNonNull(old);
columnHeader = h;
addNonNull(h);
firePropertyChange(COLUMN_HEADER_CHANGED_PROPERTY, old, h);
sync();
}
public void setColumnHeaderView(Component c)
{
if (columnHeader == null)
setColumnHeader(createViewport());
columnHeader.setView(c);
sync();
}
public void setCorner(String key, Component c)
{
if (getComponentOrientation()
== ComponentOrientation.LEFT_TO_RIGHT)
{
if (key == LOWER_LEADING_CORNER)
key = LOWER_LEFT_CORNER;
else if (key == LOWER_TRAILING_CORNER)
key = LOWER_RIGHT_CORNER;
else if (key == UPPER_LEADING_CORNER)
key = UPPER_LEFT_CORNER;
else if (key == UPPER_TRAILING_CORNER)
key = UPPER_RIGHT_CORNER;
}
else if (getComponentOrientation()
== ComponentOrientation.RIGHT_TO_LEFT)
{
if (key == LOWER_LEADING_CORNER)
key = LOWER_RIGHT_CORNER;
else if (key == LOWER_TRAILING_CORNER)
key = LOWER_LEFT_CORNER;
else if (key == UPPER_LEADING_CORNER)
key = UPPER_RIGHT_CORNER;
else if (key == UPPER_TRAILING_CORNER)
key = UPPER_LEFT_CORNER;
}
if (key == LOWER_RIGHT_CORNER)
{
removeNonNull(lowerRight);
lowerRight = c;
addNonNull(c);
}
else if (key == UPPER_RIGHT_CORNER)
{
removeNonNull(upperRight);
upperRight = c;
addNonNull(c);
}
else if (key == LOWER_LEFT_CORNER)
{
removeNonNull(lowerLeft);
lowerLeft = c;
addNonNull(c);
}
else if (key == UPPER_LEFT_CORNER)
{
removeNonNull(upperLeft);
upperLeft = c;
addNonNull(c);
}
else
throw new IllegalArgumentException("unknown corner " + key);
sync();
}
public void setHorizontalScrollBar(JScrollBar h)
{
JScrollBar old = horizontalScrollBar;
removeNonNull(old);
horizontalScrollBar = h;
addNonNull(h);
firePropertyChange(HORIZONTAL_SCROLLBAR_CHANGED_PROPERTY, old, h);
sync();
if (old != null)
{
BoundedRangeModel model = old.getModel();
if (model != null)
model.removeChangeListener(scrollListener);
}
if (h != null)
{
BoundedRangeModel model = h.getModel();
if (model != null)
model.addChangeListener(scrollListener);
}
}
public void setHorizontalScrollBarPolicy(int h)
{
if (h != HORIZONTAL_SCROLLBAR_AS_NEEDED
&& h != HORIZONTAL_SCROLLBAR_NEVER
&& h != HORIZONTAL_SCROLLBAR_ALWAYS)
throw new IllegalArgumentException("unknown horizontal scrollbar policy");
int old = horizontalScrollBarPolicy;
horizontalScrollBarPolicy = h;
firePropertyChange(HORIZONTAL_SCROLLBAR_POLICY_CHANGED_PROPERTY, old, h);
sync();
}
public void setLayout(LayoutManager l)
{
LayoutManager old = super.getLayout();
ScrollPaneLayout tmp = (ScrollPaneLayout) l;
super.setLayout(l);
tmp.syncWithScrollPane(this);
firePropertyChange(LAYOUT_CHANGED_PROPERTY, old, l);
sync();
}
public void setRowHeader(JViewport v)
{
JViewport old = rowHeader;
removeNonNull(old);
rowHeader = v;
addNonNull(v);
firePropertyChange(ROW_HEADER_CHANGED_PROPERTY, old, v);
sync();
}
public void setRowHeaderView(Component c)
{
if (rowHeader == null)
setRowHeader(createViewport());
rowHeader.setView(c);
sync();
}
public void setVerticalScrollBar(JScrollBar v)
{
JScrollBar old = verticalScrollBar;
removeNonNull(old);
verticalScrollBar = v;
addNonNull(v);
firePropertyChange(VERTICAL_SCROLLBAR_CHANGED_PROPERTY, old, v);
sync();
if (old != null)
{
BoundedRangeModel model = old.getModel();
if (model != null)
model.removeChangeListener(scrollListener);
}
if (v != null)
{
BoundedRangeModel model = v.getModel();
if (model != null)
model.addChangeListener(scrollListener);
}
}
public void setVerticalScrollBarPolicy(int v)
{
if (v != VERTICAL_SCROLLBAR_AS_NEEDED
&& v != VERTICAL_SCROLLBAR_NEVER
&& v != VERTICAL_SCROLLBAR_ALWAYS)
throw new IllegalArgumentException("unknown vertical scrollbar policy");
int old = verticalScrollBarPolicy;
verticalScrollBarPolicy = v;
firePropertyChange(VERTICAL_SCROLLBAR_POLICY_CHANGED_PROPERTY, old, v);
sync();
}
public void setWheelScrollingEnabled(boolean b)
{
boolean old = wheelScrollingEnabled;
wheelScrollingEnabled = b;
firePropertyChange(WHEEL_SCROLLING_ENABLED_CHANGED_PROPERTY, old, b);
sync();
}
public void setViewport(JViewport v)
{
JViewport old = viewport;
removeNonNull(old);
if (old != null)
old.removeChangeListener(scrollListener);
viewport = v;
if (v != null)
v.addChangeListener(scrollListener);
addNonNull(v);
revalidate();
repaint();
firePropertyChange(VIEWPORT_CHANGED_PROPERTY, old, v);
sync();
}
public void setViewportBorder(Border b)
{
Border old = viewportBorder;
viewportBorder = b;
firePropertyChange(VIEWPORT_BORDER_CHANGED_PROPERTY, old, b);
sync();
}
public void setViewportView(Component view)
{
if (getViewport() == null)
{
setViewport(createViewport());
}
if (view != null)
{
getViewport().setView(view);
}
sync();
}
public boolean isValidateRoot()
{
return true;
}
ChangeListener createScrollListener()
{
return new ChangeListener()
{
public void stateChanged(ChangeEvent event)
{
JScrollBar vsb = JScrollPane.this.getVerticalScrollBar();
JScrollBar hsb = JScrollPane.this.getHorizontalScrollBar();
JViewport vp = JScrollPane.this.getViewport();
if (vp != null && event.getSource() == vp)
{
Rectangle vr = vp.getViewRect();
Dimension vs = vp.getViewSize();
if (vsb != null
&& (vsb.getMinimum() != 0
|| vsb.getMaximum() != vs.height
|| vsb.getValue() != vr.y
|| vsb.getVisibleAmount() != vr.height))
vsb.setValue(vr.y, vr.height, 0, vs.height);
if (hsb != null
&& (hsb.getMinimum() != 0
|| hsb.getMaximum() != vs.width
|| hsb.getValue() != vr.width
|| hsb.getVisibleAmount() != vr.height))
hsb.setValue(vr.x, vr.width, 0, vs.width);
}
else
{
int xpos = 0;
int ypos = 0;
if (vsb != null)
ypos = vsb.getValue();
if (hsb != null)
xpos = hsb.getValue();
Point pt = new Point(xpos, ypos);
if (vp != null
&& vp.getViewPosition() != pt)
vp.setViewPosition(pt);
pt.x = 0;
if (rowHeader != null
&& rowHeader.getViewPosition() != pt)
rowHeader.setViewPosition(pt);
pt.x = xpos;
pt.y = 0;
if (columnHeader != null
&& columnHeader.getViewPosition() != pt)
columnHeader.setViewPosition(pt);
}
}
};
}
public JScrollPane()
{
this(null);
}
public JScrollPane(Component view)
{
this(view,
VERTICAL_SCROLLBAR_AS_NEEDED,
HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
public JScrollPane(int vsbPolicy, int hsbPolicy)
{
this(null, vsbPolicy, hsbPolicy);
}
public JScrollPane(Component view, int vsbPolicy, int hsbPolicy)
{
scrollListener = createScrollListener();
setVerticalScrollBarPolicy(vsbPolicy);
setVerticalScrollBar(createVerticalScrollBar());
setHorizontalScrollBarPolicy(hsbPolicy);
setHorizontalScrollBar(createHorizontalScrollBar());
setViewportView(view);
setLayout(new ScrollPaneLayout());
setOpaque(false);
updateUI();
}
public JScrollBar createHorizontalScrollBar()
{
return new ScrollBar(SwingConstants.HORIZONTAL);
}
public JScrollBar createVerticalScrollBar()
{
return new ScrollBar(SwingConstants.VERTICAL);
}
public JViewport createViewport()
{
return new JViewport();
}
public String getUIClassID()
{
return "ScrollPaneUI";
}
public void updateUI()
{
ScrollPaneUI b = (ScrollPaneUI)UIManager.getUI(this);
setUI(b);
}
class ScrollBar
extends JScrollBar
implements UIResource
{
public ScrollBar(int orientation)
{
super(orientation);
}
public int getBlockIncrement(int direction)
{
Component view = JScrollPane.this.getViewport().getView();
if (view == null || (! (view instanceof Scrollable)))
return super.getBlockIncrement(direction);
else
{
Scrollable s = (Scrollable) view;
return s.getScrollableBlockIncrement(JScrollPane.this.getViewport().getViewRect(),
this.getOrientation(),
direction);
}
}
public int getUnitIncrement(int direction)
{
Component view = JScrollPane.this.getViewport().getView();
if (view == null || (! (view instanceof Scrollable)))
return super.getUnitIncrement(direction);
else
{
Scrollable s = (Scrollable) view;
return s.getScrollableUnitIncrement(JScrollPane.this.getViewport().getViewRect(),
this.getOrientation(),
direction);
}
}
}
}