| /* Copyright (C) 2000 Free Software Foundation |
| |
| This file is part of libgcj. |
| |
| This software is copyrighted work licensed under the terms of the |
| Libgcj License. Please consult the file "LIBGCJ_LICENSE" for |
| details. */ |
| |
| package java.awt; |
| |
| import java.awt.event.AdjustmentListener; |
| import java.awt.peer.ScrollPanePeer; |
| |
| /** A ScrollPane is a component that has vertical and horizontal |
| * scrollbars as well as a single child which is scrolled by them. |
| * @author Tom Tromey <tromey@redhat.com> |
| * @date December 31, 2000 |
| */ |
| public class ScrollPane extends Container |
| { |
| /** This indicates that scrollbars should only be displayed when |
| * needed. */ |
| public static final int SCROLLBARS_AS_NEEDED = 0; |
| /** This indicates that scrollbars should always be displayed. */ |
| public static final int SCROLLBARS_ALWAYS = 1; |
| /** This indicates that scrollbars should never be displayed. */ |
| public static final int SCROLLBARS_NEVER = 2; |
| |
| /** Create a new ScrollPane object using the indicated scrollbar |
| * display policy. If the policy is not specified it defaults to |
| * SCROLLBARS_AS_NEEDED. The default size of this component is |
| * 100x100. |
| * @param policy The scrollbar display policy |
| */ |
| public ScrollPane () |
| { |
| this (SCROLLBARS_AS_NEEDED); |
| } |
| |
| public ScrollPane (int policy) |
| { |
| if (policy != SCROLLBARS_AS_NEEDED |
| && policy != SCROLLBARS_ALWAYS |
| && policy != SCROLLBARS_NEVER) |
| throw new IllegalArgumentException ("invalid value for policy"); |
| |
| this.policy = policy; |
| setSize (100, 100); |
| } |
| |
| /** Add a component to this ScrollPane. |
| * @param comp The component to add |
| * @param constraints Constraints. This is ignored. |
| * @param pos Position. This must be <= 0, but is otherwise ignored. |
| */ |
| protected final void addImpl (Component comp, Object constraints, |
| int pos) |
| { |
| if (pos > 0) |
| throw new IllegalArgumentException ("pos must be <= 0"); |
| |
| if (ncomponents > 0) |
| remove (component[0]); |
| |
| if (comp.isLightweight ()) |
| { |
| Panel p = new Panel (); |
| p.add (comp); |
| comp = p; |
| } |
| |
| super.addImpl (comp, constraints, pos); |
| } |
| |
| /** This creates the component's peer. */ |
| public void addNotify () |
| { |
| if (peer == null) |
| peer = getToolkit ().createScrollPane (this); |
| super.addNotify (); |
| } |
| |
| /** Lays out the components in this container. */ |
| public void doLayout () |
| { |
| ScrollPanePeer spp = (ScrollPanePeer) peer; |
| Dimension c = component[0].getPreferredSize (); |
| component[0].setSize (c.width, c.height); |
| spp.childResized (c.width, c.height); |
| // Update the scrollbar position to the closest valid value. |
| setScrollPosition (hscroll.getValue (), vscroll.getValue ()); |
| } |
| |
| /** Returns an Adjustable representing the horizontal scrollbar. |
| * The methods setMaximum, setMinimum, and setVisibleAmount should |
| * not be called on this Adjustable. They will throw AWTError if |
| * called. |
| */ |
| public Adjustable getHAdjustable () |
| { |
| return hscroll; |
| } |
| |
| /** Returns the height of the horizontal scrollbar. */ |
| public int getHScrollbarHeight () |
| { |
| if (peer == null) |
| return 0; |
| ScrollPanePeer spp = (ScrollPanePeer) peer; |
| return spp.getHScrollbarHeight (); |
| } |
| |
| /** Returns the scrollbar display policy. */ |
| public int getScrollbarDisplayPolicy () |
| { |
| return policy; |
| } |
| |
| /** Returns the viewport's scroll position. */ |
| public Point getScrollPosition () |
| { |
| return new Point (hscroll.getValue (), vscroll.getValue ()); |
| } |
| |
| /** Returns an Adjustable representing the vertical scrollbar. |
| * The methods setMaximum, setMinimum, and setVisibleAmount should |
| * not be called on this Adjustable. They will throw AWTError if |
| * called. |
| */ |
| public Adjustable getVAdjustable () |
| { |
| return vscroll; |
| } |
| |
| /** Returns the size of the viewport. */ |
| public Dimension getViewportSize () |
| { |
| // Note: according to the online docs, the Insets are |
| // automatically updated by the peer to include the scrollbar |
| // sizes. |
| Insets ins = getInsets (); |
| int myw = width - ins.left - ins.right; |
| int myh = height - ins.top - ins.bottom; |
| |
| Dimension cs; |
| if (ncomponents > 0) |
| cs = component[0].getPreferredSize (); |
| else |
| cs = new Dimension (myw, myh); |
| |
| // A little optimization -- reuse the Dimension. |
| cs.setSize (myw, myh); |
| return cs; |
| } |
| |
| /** Returns the width of the vertical scrollbar. */ |
| public int getVScrollbarWidth () |
| { |
| if (peer == null) |
| return 0; |
| ScrollPanePeer spp = (ScrollPanePeer) peer; |
| return spp.getVScrollbarWidth (); |
| } |
| |
| /** Generates a String representation of this ScrollPane's state. */ |
| public String paramString () |
| { |
| return ("[" + getClass ().getName () |
| + ": " + ((ncomponents > 0) ? component[0].paramString () : "") |
| + "]"); |
| } |
| |
| /** Set the layout manager for this component. ScrollPane has its |
| * own layout manager and overrides this method so that the layout |
| * manager cannot be changed. |
| * @param m The new layout manager (ignored) |
| */ |
| public final void setLayout (LayoutManager m) |
| { |
| // Nothing. |
| } |
| |
| /** Sets the scroll position for this ScrollPane. If the point if |
| * out of range it is silently moved within range. |
| * @param x The x coordinate |
| * @param y The y coordinate |
| */ |
| public void setScrollPosition (int x, int y) |
| { |
| // According to the JCL we throw a NullPointerException if there |
| // is no child. |
| if (ncomponents == 0) |
| throw new NullPointerException ("no child in ScrollPane"); |
| |
| Dimension child_d = component[0].getPreferredSize (); |
| Dimension our_d = getViewportSize (); |
| |
| int xmax = Math.max (0, child_d.width - our_d.width); |
| int ymax = Math.max (0, child_d.height - our_d.height); |
| |
| if (x < 0) |
| x = 0; |
| else if (x > xmax) |
| x = xmax; |
| if (y < 0) |
| y = 0; |
| else if (y > ymax) |
| y = ymax; |
| |
| ScrollPanePeer spp = (ScrollPanePeer) peer; |
| spp.setScrollPosition (x, y); |
| } |
| |
| /** Sets the scroll position for this ScrollPane. If the point if |
| * out of range it is silently moved within range. |
| * @param p The new point |
| */ |
| public void setScrollPosition (Point p) |
| { |
| setScrollPosition (p.x, p.y); |
| } |
| |
| // This implements the Adjustable for each scrollbar. The |
| // expectation is that the peer will look at these objects directly |
| // and modify the values in them when the user manipulates the |
| // scrollbars. This has to be done from CNI to bypass Java |
| // protection rules. The peer should also take care of calling the |
| // adjustment listeners. |
| class ScrollPaneAdjustable implements Adjustable |
| { |
| AdjustmentListener listeners; |
| int orient; |
| int unit; |
| int block; |
| int value; |
| |
| public ScrollPaneAdjustable (int orient) |
| { |
| this.orient = orient; |
| } |
| |
| public void addAdjustmentListener (AdjustmentListener l) |
| { |
| listeners = AWTEventMulticaster.add (listeners, l); |
| } |
| |
| public int getBlockIncrement () |
| { |
| return block; |
| } |
| |
| public int getMaximum () |
| { |
| Dimension child_d = component[0].getPreferredSize (); |
| Dimension our_d = getViewportSize (); |
| |
| int xmax = Math.max (0, child_d.width - our_d.width); |
| int ymax = Math.max (0, child_d.height - our_d.height); |
| |
| return (orient == Adjustable.HORIZONTAL) ? xmax : ymax; |
| } |
| |
| public int getMinimum () |
| { |
| return 0; |
| } |
| |
| public int getOrientation () |
| { |
| return orient; |
| } |
| |
| public int getUnitIncrement () |
| { |
| return unit; |
| } |
| |
| public int getValue () |
| { |
| return value; |
| } |
| |
| public int getVisibleAmount () |
| { |
| Dimension d = getViewportSize (); |
| return (orient == Adjustable.HORIZONTAL) ? d.width : d.height; |
| } |
| |
| public void removeAdjustmentListener (AdjustmentListener l) |
| { |
| listeners = AWTEventMulticaster.remove (listeners, l); |
| } |
| |
| public void setBlockIncrement (int b) |
| { |
| throw new AWTError ("can't use setBlockIncrement on this Adjustable"); |
| } |
| |
| public void setMaximum (int max) |
| { |
| throw new AWTError ("can't use setMaximum on this Adjustable"); |
| } |
| |
| public void setMinimum (int min) |
| { |
| throw new AWTError ("can't use setMinimum on this Adjustable"); |
| } |
| |
| public void setUnitIncrement (int u) |
| { |
| unit = u; |
| if (peer != null) |
| { |
| ScrollPanePeer spp = (ScrollPanePeer) peer; |
| spp.setUnitIncrement (this, u); |
| } |
| } |
| |
| public void setValue (int v) |
| { |
| value = v; |
| if (peer != null) |
| { |
| ScrollPanePeer spp = (ScrollPanePeer) peer; |
| spp.setValue (this, v); |
| } |
| } |
| |
| public void setVisibleAmount (int v) |
| { |
| throw new AWTError ("can't use setVisibleAmount on this Adjustable"); |
| } |
| } |
| |
| ScrollPaneAdjustable hscroll |
| = new ScrollPaneAdjustable (Adjustable.HORIZONTAL); |
| ScrollPaneAdjustable vscroll |
| = new ScrollPaneAdjustable (Adjustable.VERTICAL); |
| int policy; |
| } |