仅使用Panel或任何其他Container自定义ScrollPane

时间:2012-02-17 09:03:25

标签: java scroll awt

我试图通过简单地从ScrollPane继承来模仿PanelsetScrollPosition(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}}

0 个答案:

没有答案