package com.HorizonLive.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); } }