我试图通过简单地从ScrollPane
继承来模仿Panel
,setScrollPosition(Point)
本身会移动它的孩子。
应该是一个简单的任务,但是孩子没有被正确剪裁,这意味着如果我使用Panel
滚动,内容是可见的,尽管它在父public class ScrollFrame
extends Container
{
public ScrollFrame() {
setLayout(null);
}
public void paint(Graphics g) {
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
super.paint(g);
}
public void setScrollPosition(Point p) {
setScrollPosition(p.x, p.y);
}
public void setScrollPosition(int x, int y) {
synchronized (getTreeLock()) {
Component component = getComponent(0);
int viewPortWidth = getWidth(),
viewPortHeight = getHeight(),
componentWidth = component.getWidth(),
componentHeight = component.getHeight(),
componentX = component.getX(),
componentY = component.getY();
if (x < 0) {
x = 0;
} else if (x > 0 && x + viewPortWidth > componentWidth) {
x = componentWidth - viewPortWidth;
if (x < 0)
x = 0;
}
if (y < 0) {
y = 0;
} else if (y > 0 && y + viewPortHeight > componentHeight) {
y = componentHeight - viewPortHeight;
if (y < 0)
y = 0;
}
component.setLocation(x * -1, y * -1);
validate();
}
}
public Point getScrollPosition() {
synchronized (getTreeLock()) {
Point p = getComponent(0).getLocation();
p.x *= -1;
p.y *= -1;
return p;
}
}
}
之外。
ScrollFrame
问题:添加到ScrollFrame
的子组件在import java.awt.*;
import java.awt.event.*;
public class TestScrollPane extends Frame implements MouseListener,
MouseMotionListener
{
/* starting point */
public static void main(String[] args)
{
TestScrollPane window = new TestScrollPane();
window.setSize(800, 480);
window.setVisible(true);
}
/*
* a translucent element to be placed above all other components to receive
* the MouseEvents
*/
public class GlassPane extends Component
{
public void paint(Graphics g)
{
g.setColor(Color.RED);
g.fillRect(0, 0, getWidth(), getHeight());
super.paint(g);
}
}
public class ScrollContainer extends Container
{
public ScrollContainer()
{
setLayout(null);
}
public void paint(Graphics g)
{
g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
super.paint(g);
}
public void printComponents(Graphics g)
{
Component c = getComponent(0);
Point p = c.getLocation();
Graphics cg = g.create();
try {
cg.clipRect(0, 0, getWidth(), getHeight());
cg.translate(p.x * -1, p.y * -1);
c.paintAll(cg);
} finally {
cg.dispose();
}
}
public void setScrollPosition(Point p)
{
setScrollPosition(p.x, p.y);
}
public void setScrollPosition(int x, int y)
{
synchronized (getTreeLock()) {
Component component = getComponent(0);
int viewPortWidth = getWidth(), viewPortHeight = getHeight(), componentWidth = component
.getWidth(), componentHeight = component.getHeight(), componentX = component
.getX(), componentY = component.getY();
if (x < 0) {
x = 0;
} else if (x > 0 && x + viewPortWidth > componentWidth) {
x = componentWidth - viewPortWidth;
if (x < 0)
x = 0;
}
if (y < 0) {
y = 0;
} else if (y > 0 && y + viewPortHeight > componentHeight) {
y = componentHeight - viewPortHeight;
if (y < 0)
y = 0;
}
component.setLocation(x * -1, y * -1);
}
}
public Point getScrollPosition()
{
synchronized (getTreeLock()) {
Point p = getComponent(0).getLocation();
p.x *= -1;
p.y *= -1;
return p;
}
}
}
private ScrollContainer scrollPane;
private Panel scrollPaneContainer;
private GlassPane glassPane;
private boolean scrolling = false;
private Point scrollingStartMouse;
private Point scrollingStartPane;
public TestScrollPane()
{
/* simple test window */
super("TestScrollPane");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e)
{
e.getWindow().dispose();
System.exit(0);
}
});
setLayout(null);
/*
* the ScrollPane provides the ability to show only a limited of a much
* larger child element. Note that the ScrollPane is a container for
* only ONE element, but the child element may act as a container, e.g.
* a Panel
*/
scrollPane = new ScrollContainer();
scrollPane.addMouseListener(this);
scrollPane.setBounds(30, 50, 300, 300);
/*
* the element we place in the scrollpane, a panel with null layout to
* place the children
*/
scrollPaneContainer = new Panel();
scrollPaneContainer.setLayout(null);
/* add some random buttons for testing purposes */
for (int i = 0; i < 30; ++i) {
Button button = new Button("Click Me " + i);
button.addMouseListener(this);
button.setBounds(0, 40 * i, 100, 30);
scrollPaneContainer.add(button);
}
/*
* a translucent component on top of all elements placed inside the
* scrollPaneContainer to receive the MouseEvent's and properly scroll
* the ScrollPane or propagate the event
*/
glassPane = new GlassPane();
glassPane.setBounds(0, 0, 1, 1);
glassPane.addMouseListener(this);
glassPane.addMouseMotionListener(this);
/*
* we do need to add the GlassPane first to place it above all other
* elements
*/
// scrollPaneContainer.add(glassPane);
/*
* the GlassPane and the scrollPaneContainer need to have the same size.
* you have to set a size on the scrollPaneContainer else there won't be
* any scrolling ;)
*/
scrollPaneContainer.setSize(100, 1190);
scrollPaneContainer.setPreferredSize(new Dimension(100, 1190));
/* place the scrollPaneContainer (Panel) inside the ScrollPane */
scrollPane.add(scrollPaneContainer);
scrollPane.setBounds(30, 30, 150, 300);
glassPane.setBounds(30, 30, 30, 300);
Panel all = new Panel();
all.setLayout(null);
all.setBounds(30, 30, 400, 400);
all.add(glassPane);
all.add(scrollPane);
add(all);
}
/* MouseListener implementation */
public void mouseClicked(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
public void mouseReleased(MouseEvent e)
{
if (e.getSource().equals(glassPane)) {
scrolling = false;
}
}
public void mousePressed(MouseEvent e)
{
if (e.getSource().equals(glassPane)) {
scrolling = true;
scrollingStartMouse = e.getPoint();
scrollingStartPane = scrollPane.getScrollPosition();
}
}
/* MouseMotionListener implementation */
public void mouseDragged(MouseEvent e)
{
if (scrolling) {
Point currentPos = e.getPoint();
int mouseDeltaX = currentPos.x - scrollingStartMouse.x;
int mouseDeltaY = currentPos.y - scrollingStartMouse.y;
scrollPane.setScrollPosition(scrollingStartPane.x - mouseDeltaX,
scrollingStartPane.y - mouseDeltaY);
}
}
public void mouseMoved(MouseEvent e)
{
}
void log(String message)
{
System.out.println(message);
}
void log(String message, MouseEvent e)
{
log(e.getComponent().getClass().getName() + ": " + message);
}
}
的边界外可见。
最后用于某些C&amp; P测试的SSCCE,只需点击红色区域并上下移动鼠标:
{{1}}