ScrollPanel.java revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* ident "%Z%%M% %I% %E% SMI"
*
* Copyright (c) 2000 by Sun Microsystems, Inc.
* All rights reserved.
*/
/*
* Copyright (C) 1996 Active Software, Inc.
* All rights reserved.
*
* @(#) ScrollPanel.java 1.41 - last change made 07/25/97
*/
package sunsoft.jws.visual.rt.awt;
import sunsoft.jws.visual.rt.awt.*;
import sunsoft.jws.visual.rt.base.Global;
import sunsoft.jws.visual.rt.base.Util;
import java.awt.*;
public class ScrollPanel extends VJPanel {
protected VJScrollbar vbar, hbar;
private Component comp;
private boolean vshow, hshow;
private GBLayout gridbag;
private boolean hasFocus;
private int scrollAreaWidth = 0;
private int scrollAreaHeight = 0;
private Insets scrollAreaInsets;
public ScrollPanel() {
super(Util.WIN95_FIELD_BORDER);
setBorderInsets(new Insets(0, 0, 0, 0));
GBConstraints c = new GBConstraints();
gridbag = new GBLayout();
setLayout(gridbag);
hbar = new VJScrollbar(VJScrollbar.HORIZONTAL);
vbar = new VJScrollbar(VJScrollbar.VERTICAL);
c.gridx = 1;
c.gridy = 0;
c.shrinkx = false;
c.shrinky = true;
c.fill = GBConstraints.VERTICAL;
// #ifdef JDK1.1
super.addImpl(vbar, null, -1);
// #else
// super.add(vbar, -1);
// #endif
gridbag.setConstraints(vbar, c);
c.gridx = 0;
c.gridy = 1;
c.shrinkx = true;
c.shrinky = false;
c.fill = GBConstraints.HORIZONTAL;
// #ifdef JDK1.1
super.addImpl(hbar, null, -1);
// #else
// super.add(hbar, -1);
// #endif
gridbag.setConstraints(hbar, c);
// Have the initial minimumSize include the vertical scrollbar,
// but not the horizontal scrollbar.
vshow = true;
hbar.hide();
}
// #ifdef JDK1.1
protected void addImpl(Component comp, Object constraints,
int index) {
super.addImpl(comp, constraints, index);
doAdd(comp);
}
// #else
// public Component add(Component comp, int pos) {
// super.add(comp, pos);
// doAdd(comp);
// return comp;
// }
// #endif
private void doAdd(Component comp) {
if (!(comp instanceof Scrollable))
throw new Error(Global.getMsg(
"sunsoft.jws.visual.rt.awt.ScrollPanel.OnlyOneInstance"));
if (this.comp != null)
remove(this.comp);
this.comp = comp;
GBConstraints c = new GBConstraints();
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
c.weighty = 1;
c.shrinkx = true;
c.shrinky = true;
c.fill = GBConstraints.BOTH;
c.insets = scrollAreaInsets;
gridbag.setConstraints(comp, c);
}
public int getScrollAreaWidth() {
return scrollAreaWidth;
}
public void setScrollAreaWidth(int scrollAreaWidth) {
this.scrollAreaWidth = scrollAreaWidth;
}
public int getScrollAreaHeight() {
return scrollAreaHeight;
}
public void setScrollAreaHeight(int scrollAreaHeight) {
this.scrollAreaHeight = scrollAreaHeight;
}
public Insets getScrollAreaInsets() {
return scrollAreaInsets;
}
public void setScrollAreaInsets(Insets insets) {
scrollAreaInsets = insets;
if (comp != null) {
GBConstraints c = gridbag.getConstraints(comp);
c.insets = insets;
gridbag.setConstraints(comp, c);
}
}
public int getVisibleIndex() {
if (!vshow)
return 0;
int lineHeight = ((Scrollable)comp).lineHeight();
int scrolly = vbar.getValue();
return (scrolly+lineHeight-1)/lineHeight;
}
public void makeVisible(int index) {
if (!vshow)
return;
if (index == -1)
return;
Scrollable scrollable = (Scrollable)comp;
Dimension viewSize = scrollable.viewSize(comp.size());
int lineHeight = scrollable.lineHeight();
int y = lineHeight*index;
int scrolly = vbar.getValue();
if (y < scrolly) {
vbar.setValue(y);
scrollable.scrollY(y);
} else if ((y + lineHeight) > scrolly + viewSize.height) {
y -= (viewSize.height - lineHeight);
if (y < 0)
y = 0;
vbar.setValue(y);
scrollable.scrollY(y);
}
}
public boolean handleEvent(Event e) {
if (e.id == Event.GOT_FOCUS) {
hasFocus = true;
return super.handleEvent(e);
} else if (e.id == Event.LOST_FOCUS) {
hasFocus = false;
return super.handleEvent(e);
} else if (e.target == hbar)
((Scrollable)comp).scrollX(hbar.getValue());
else if (e.target == vbar)
((Scrollable)comp).scrollY(vbar.getValue());
else
return super.handleEvent(e);
return true;
}
private Dimension viewSize() {
Dimension size = size();
size = new Dimension(size.width, size.height);
// take out our insets
Insets insets = insets();
Insets scrollAreaInsets = getScrollAreaInsets();
if (scrollAreaInsets == null)
scrollAreaInsets = new Insets(0, 0, 0, 0);
size.width -= (insets.left + insets.right +
scrollAreaInsets.left + scrollAreaInsets.right);
size.height -= (insets.top + insets.bottom +
scrollAreaInsets.top + scrollAreaInsets.bottom);
return ((Scrollable)comp).viewSize(size);
}
// Always leave space for the scrollbars
public Dimension minimumSize() {
Dimension compMin;
Dimension hbarMin = hbar.minimumSize();
Dimension vbarMin = vbar.minimumSize();
if (comp != null) {
compMin = comp.minimumSize();
compMin = new Dimension(compMin.width, compMin.height);
}
else
compMin = new Dimension(0, 0);
return calcSize(compMin, hbarMin, vbarMin);
}
// Always leave space for the scrollbars
public Dimension preferredSize() {
Dimension compPref;
Dimension hbarPref = hbar.preferredSize();
Dimension vbarPref = vbar.preferredSize();
if (comp != null) {
compPref = comp.preferredSize();
compPref = new Dimension(compPref.width, compPref.height);
}
else
compPref = new Dimension(0, 0);
return calcSize(compPref, hbarPref, vbarPref);
}
private Dimension calcSize(Dimension compMin,
Dimension hbarMin, Dimension vbarMin) {
Insets insets = insets();
Insets scrollAreaInsets = getScrollAreaInsets();
if (scrollAreaInsets == null)
scrollAreaInsets = new Insets(0, 0, 0, 0);
if (scrollAreaWidth != 0)
compMin.width = scrollAreaWidth;
if (scrollAreaHeight != 0)
compMin.height = scrollAreaHeight;
int insetsWidth = insets.left + insets.right +
scrollAreaInsets.left + scrollAreaInsets.right;
compMin.width += (vbarMin.width + insetsWidth);
compMin.width = Math.max(compMin.width, (hbarMin.width +
insetsWidth));
int insetsHeight = insets.top + insets.bottom +
scrollAreaInsets.top + scrollAreaInsets.bottom;
compMin.height += (hbarMin.height + insetsHeight);
compMin.height = Math.max(compMin.height, (vbarMin.height +
insetsHeight));
return compMin;
}
public void layout() {
boolean hadFocus = hasFocus;
Dimension viewSize = viewSize();
if (viewSize.width <= 0 || viewSize.height <= 0) {
super.layout();
return;
}
Dimension d;
Dimension scrollSize = ((Scrollable)comp).scrollSize();
boolean needHShow = false, needVShow = false;
boolean revalidate = false;
if (viewSize.width < scrollSize.width)
needHShow = true;
if (viewSize.height < scrollSize.height)
needVShow = true;
if ((needHShow || needVShow) && !(needHShow && needVShow)) {
if (needVShow) {
d = vbar.minimumSize();
if (viewSize.width < (scrollSize.width + d.width))
needHShow = true;
} else if (needHShow) {
d = hbar.minimumSize();
if (viewSize.height < (scrollSize.height + d.height))
needVShow = true;
}
}
if (needHShow) {
if (!hshow) {
hbar.show();
hshow = true;
revalidate = true;
}
} else {
if (hshow) {
hbar.hide();
hshow = false;
revalidate = true;
if (hbar.getValue() != 0)
hbar.setValue(0);
((Scrollable)comp).scrollX(0);
}
}
if (needVShow) {
if (!vshow) {
vbar.show();
vshow = true;
revalidate = true;
}
} else {
if (vshow) {
vbar.hide();
vshow = false;
revalidate = true;
if (vbar.getValue() != 0)
vbar.setValue(0);
((Scrollable)comp).scrollY(0);
}
}
if (hshow)
updateHScrollbar();
if (vshow)
updateVScrollbar();
if (revalidate) {
validate();
if (hadFocus && Global.isMotif())
comp.requestFocus();
} else {
super.layout();
}
}
public void updateWindow() {
invalidate();
validate();
}
protected void updateHScrollbar() {
Dimension viewSize = viewSize();
Dimension scrollSize = ((Scrollable)comp).scrollSize();
if (vshow) {
Dimension d = vbar.minimumSize();
viewSize.width -= d.width;
}
// (viewSize.width-d.width) can become negative
// during initialization
if (viewSize.width < 1)
return;
int maximum = scrollSize.width;
// #ifndef MAXIMUM_HACK
// maximum -= viewSize.width;
// #endif
hbar.setValues(hbar.getValue(), viewSize.width, 0, maximum);
Scrollable scrollable = (Scrollable)comp;
int lineWidth = Math.max(10, viewSize.width/6);
int pageSize = Math.max(lineWidth, viewSize.width - lineWidth);
pageSize = Math.min(scrollSize.width - viewSize.width,
pageSize);
hbar.setLineIncrement(lineWidth);
hbar.setPageIncrement(pageSize);
scrollable.scrollX(hbar.getValue());
}
protected void updateVScrollbar() {
Dimension viewSize = viewSize();
Dimension scrollSize = ((Scrollable)comp).scrollSize();
if (hshow) {
Dimension d = hbar.minimumSize();
viewSize.height -= d.height;
}
// (viewSize.height-d.height) can become
// negative during initialization
if (viewSize.height < 1)
return;
int maximum = scrollSize.height;
// #ifndef MAXIMUM_HACK
// maximum -= viewSize.height;
// #endif
vbar.setValues(vbar.getValue(), viewSize.height, 0, maximum);
Scrollable scrollable = (Scrollable)comp;
int lineHeight = scrollable.lineHeight();
int pageSize =
Math.max(lineHeight,
(viewSize.height/lineHeight)*lineHeight - lineHeight);
pageSize = Math.min(scrollSize.height-viewSize.height,
pageSize);
vbar.setLineIncrement(lineHeight);
vbar.setPageIncrement(pageSize);
scrollable.scrollY(vbar.getValue());
}
}