blob: 7325c8c97f21cf963b0add0ff2552624de83789d [file] [log] [blame]
package com.tightvnc.rfbplayer;
import java.awt.*;
import java.awt.event.*;
class LWScrollPane extends Container implements AdjustmentListener {
/** position info */
private Point scrollPosition = new Point(0, 0);
/** panel to hold component to scroll */
private Panel innerPanel = new Panel() {
public void update(Graphics g) {
if (needClear) {
super.update(g);
needClear = false;
} else
this.paint(g);
}
};
/** component to display */
private Component containedComp;
/** layout info */
private GridBagLayout gb;
private GridBagConstraints gbc;
/** scroll bars */
private Scrollbar xScroller;
private Scrollbar yScroller;
/** flags indicating which scollbars are visible */
private boolean showingXScroll = false;
private boolean showingYScroll = false;
/** flag indicating when innerpanel needs to repaint background */
private boolean needClear = false;
/** dimensions for our preferred size */
private int width = 0;
private int height = 0;
/** c'tor for a new scroll pane */
public LWScrollPane() {
// create scroll bars
xScroller = new Scrollbar(Scrollbar.HORIZONTAL) {
public boolean isFocusable() {
return false;
}
};
yScroller = new Scrollbar(Scrollbar.VERTICAL) {
public boolean isFocusable() {
return false;
}
};
xScroller.addAdjustmentListener(this);
yScroller.addAdjustmentListener(this);
// layout info
gb = new GridBagLayout();
gbc = new GridBagConstraints();
setLayout(gb);
setBackground(Color.white);
// added inner panel
//innerPanel.setBackground(Color.blue);
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = 100;
gbc.weighty = 100;
gb.setConstraints(innerPanel, gbc);
add(innerPanel);
innerPanel.setLayout(null);
}
/*
public void update(Graphics g) {
paint(g);
}
*/
/*
public void paint(Graphics g) {
super.paint(g);
}
*/
/**
* Provided to allow the containing frame to resize.
* OS X JVM 1.3 would not allow a frame to be made
* smaller without overriding getMinimumSize.
*/
public Dimension getMinimumSize() {
return new Dimension(0, 0);
}
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
public void setSize(int width, int height) {
this.width = width;
this.height = height;
super.setSize(width, height);
}
public void setSize(Dimension d) {
setSize(d.width, d.height);
}
/**
* Force component to clear itself before repainting.
* Primarily useful if the contained component shrinks
* without the scroll pane reducing in size.
*/
public void clearAndRepaint() {
needClear = true;
innerPanel.repaint();
}
/** Add the component to be scrolled by scroll pane */
void addComp(Component comp) {
containedComp = comp;
innerPanel.add(containedComp);
}
/**
* Set the point of the component to display in the
* upper left corner of the viewport.
*/
void setScrollPosition(int x, int y) {
Dimension vps = getViewportSize();
Dimension ccs = containedComp.getPreferredSize();
// skip entirely if component smaller than viewer
if (ccs.width <= vps.width && ccs.height <= vps.height)
return;
// don't scroll too far left or up
if (x < 0)
x = 0;
if (y < 0)
y = 0;
// don't scroll too far right or down
if (ccs.width <= vps.width)
x = 0;
else if (x > (ccs.width - vps.width))
x = ccs.width - vps.width;
if (ccs.height <= vps.height)
y = 0;
else if (y > (ccs.height - vps.height))
y = ccs.height - vps.height;
scrollPosition = new Point(x, y);
containedComp.setLocation(-scrollPosition.x, -scrollPosition.y);
xScroller.setValue(scrollPosition.x);
yScroller.setValue(scrollPosition.y);
}
/** Returns the point at the upper left corner of viewport */
Point getScrollPosition() {
return new Point(scrollPosition);
}
/** Return the dimensions of the viewport */
public Dimension getViewportSize() {
int vpW, vpH;
Dimension size = getSize();
vpW = size.width;
vpH = size.height;
if (showingYScroll)
vpW -= yScroller.getSize().width;
if (showingXScroll)
vpH -= xScroller.getSize().height;
return new Dimension(vpW, vpH);
}
/**
* Ensure that the scroll pane is properly arranged after
* a component is added, the pane is resized, etc.
*/
public void doLayout() {
/** Add scroll bars as necessary */
boolean needX = false, needY = false;
Dimension innerSize = containedComp.getPreferredSize();
Dimension scrollDimension = getSize();
if (innerSize.width > scrollDimension.width)
needX = true;
if (innerSize.height > scrollDimension.height)
needY = true;
showingXScroll = false;
showingYScroll = false;
remove(yScroller);
remove(xScroller);
if (needY) {
gbc.gridy = 0;
gbc.gridx = 1;
gbc.weightx = 0;
gb.setConstraints(yScroller, gbc);
add(yScroller);
showingYScroll = true;
}
if (needX) {
gbc.gridy = 1;
gbc.gridx = 0;
gbc.weightx = 100;
gbc.weighty = 0;
gb.setConstraints(xScroller, gbc);
add(xScroller);
showingXScroll = true;
}
/* set scroll bar values */
int vpW, vpH;
vpW = scrollDimension.width;
vpH = scrollDimension.height;
if (showingYScroll)
vpW -= yScroller.getSize().width;
if (showingXScroll)
vpH -= xScroller.getSize().height;
yScroller.setValues(0, vpH, 0, innerSize.height);
xScroller.setValues(0, vpW, 0, innerSize.width);
containedComp.setLocation(0, 0);
super.doLayout();
}
/**
* Adjustment listener method for receiving callbacks
* from scroll actions.
*
* @param e the AdjustmentEvent
* @return void
*/
public void adjustmentValueChanged(AdjustmentEvent e) {
Point p = containedComp.getLocation();
if (e.getAdjustable() == xScroller) {
p.x = -e.getValue();
scrollPosition.x = e.getValue();
} else {
p.y = -e.getValue();
scrollPosition.y = e.getValue();
}
containedComp.setLocation(p);
}
}