summaryrefslogtreecommitdiff
path: root/libjava/classpath/javax/swing/JViewport.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/classpath/javax/swing/JViewport.java')
-rw-r--r--libjava/classpath/javax/swing/JViewport.java490
1 files changed, 490 insertions, 0 deletions
diff --git a/libjava/classpath/javax/swing/JViewport.java b/libjava/classpath/javax/swing/JViewport.java
new file mode 100644
index 00000000000..397cb31acdf
--- /dev/null
+++ b/libjava/classpath/javax/swing/JViewport.java
@@ -0,0 +1,490 @@
+/* JViewport.java --
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING. If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library. Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module. An independent module is a module which is not derived from
+or based on this library. If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so. If you do not wish to do so, delete this
+exception statement from your version. */
+
+
+package javax.swing;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.io.Serializable;
+
+import javax.swing.border.Border;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.plaf.ViewportUI;
+
+/**
+ *
+ * <pre>
+ * _
+ * +-------------------------------+ ...........Y1 \
+ * | view | . \
+ * | (this component's child) | . > VY
+ * | | . / = Y2-Y1
+ * | +------------------------------+ ....Y2_/
+ * | | viewport | | .
+ * | | (this component) | | .
+ * | | | | .
+ * | | | | .
+ * | | | | .
+ * | | | | .
+ * | +------------------------------+ ....Y3
+ * | | .
+ * | . | . .
+ * | . | . .
+ * +---------.---------------------+ ...........Y4
+ * . . . .
+ * . . . .
+ * . . . .
+ * X1.......X2.....................X3.......X4
+ * \____ ___/
+ * \/
+ * VX = X2-X1
+ *</pre>
+ *
+ * <p>A viewport is, like all swing components, located at some position in
+ * the swing component tree; that location is exactly the same as any other
+ * components: the viewport's "bounds".</p>
+ *
+ * <p>But in terms of drawing its child, the viewport thinks of itself as
+ * covering a particular position <em>of the view's coordinate space</em>.
+ * For example, the {@link javax.JViewPort.getViewPosition} method returns
+ * the position <code>(VX,VY)</code> shown above, which is an position in
+ * "view space", even though this is <em>implemented</em> by positioning
+ * the underlying child at position <code>(-VX,-VY)</code></p>
+ *
+ */
+public class JViewport extends JComponent
+{
+
+ /**
+ * A {@link java.awt.event.ComponentListener} that listens for
+ * changes of the view's size. This class forbids changes of the view
+ * component's size that would exceed the viewport's size.
+ */
+ protected class ViewListener
+ extends ComponentAdapter
+ implements Serializable
+ {
+ private static final long serialVersionUID = -2812489404285958070L;
+
+ /**
+ * Creates a new instance of ViewListener.
+ */
+ protected ViewListener()
+ {
+ }
+
+ /**
+ * Receives notification when a component (in this case: the view
+ * component) changes it's size.
+ *
+ * @param ev the ComponentEvent describing the change
+ */
+ public void componentResized(ComponentEvent ev)
+ {
+ // According to some tests that I did with Sun's implementation
+ // this class is supposed to make sure that the view component
+ // is not resized to a larger size than the viewport.
+ // This is not documented anywhere. What I did is: I subclassed JViewport
+ // and ViewListener and 'disabled' the componentResized method by
+ // overriding it and not calling super.componentResized().
+ // When this method is disabled I can set the size on the view component
+ // normally, when it is enabled, it gets immediatly resized back,
+ // after a resize attempt that would exceed the Viewport's size.
+ Component comp = ev.getComponent();
+ Dimension newSize = comp.getSize();
+ Dimension viewportSize = getSize();
+ boolean revert = false;
+ if (newSize.width > viewportSize.width)
+ {
+ newSize.width = viewportSize.width;
+ revert = true;
+ }
+ if (newSize.height > viewportSize.height)
+ {
+ newSize.height = viewportSize.height;
+ revert = true;
+ }
+ if (revert == true)
+ comp.setSize(newSize);
+ }
+ }
+
+ private static final long serialVersionUID = -6925142919680527970L;
+
+ public static final int SIMPLE_SCROLL_MODE = 0;
+ public static final int BLIT_SCROLL_MODE = 1;
+ public static final int BACKINGSTORE_SCROLL_MODE = 2;
+
+ ChangeEvent changeEvent = new ChangeEvent(this);
+
+ int scrollMode;
+
+ protected boolean scrollUnderway;
+ protected boolean isViewSizeSet;
+
+ /**
+ * The width and height of the Viewport's area in terms of view
+ * coordinates. Typically this will be the same as the width and height
+ * of the viewport's bounds, unless the viewport transforms units of
+ * width and height, which it may do, for example if it magnifies or
+ * rotates its view.
+ *
+ * @see #toViewCoordinates
+ */
+ Dimension extentSize;
+
+ /**
+ * The width and height of the view in its own coordinate space.
+ */
+
+ Dimension viewSize;
+
+ Point lastPaintPosition;
+
+ /**
+ * The ViewListener instance.
+ */
+ ViewListener viewListener;
+
+ public JViewport()
+ {
+ setOpaque(true);
+ setScrollMode(BLIT_SCROLL_MODE);
+ setLayout(createLayoutManager());
+ updateUI();
+ }
+
+ public Dimension getExtentSize()
+ {
+ if (extentSize == null)
+ return toViewCoordinates(getSize());
+ else
+ return extentSize;
+ }
+
+ public Dimension toViewCoordinates(Dimension size)
+ {
+ return size;
+ }
+
+ public Point toViewCoordinates(Point p)
+ {
+ Point pos = getViewPosition();
+ return new Point(p.x + pos.x,
+ p.y + pos.y);
+ }
+
+ public void setExtentSize(Dimension newSize)
+ {
+ extentSize = newSize;
+ fireStateChanged();
+ }
+
+ /**
+ * Returns the viewSize when set, or the preferred size of the set
+ * Component view. If no viewSize and no Component view is set an
+ * empty Dimension is returned.
+ */
+ public Dimension getViewSize()
+ {
+ if (isViewSizeSet)
+ return viewSize;
+ else
+ {
+ Component view = getView();
+ if (view != null)
+ return view.getPreferredSize();
+ else
+ return new Dimension();
+ }
+ }
+
+
+ public void setViewSize(Dimension newSize)
+ {
+ viewSize = newSize;
+ Component view = getView();
+ if (view != null)
+ view.setSize(viewSize);
+ isViewSizeSet = true;
+ fireStateChanged();
+ }
+
+ /**
+ * Get the viewport's position in view space. Despite confusing name,
+ * this really does return the viewport's (0,0) position in view space,
+ * not the view's position.
+ */
+
+ public Point getViewPosition()
+ {
+ Component view = getView();
+ if (view == null)
+ return new Point(0,0);
+ else
+ {
+ Point p = view.getLocation();
+ p.x = -p.x;
+ p.y = -p.y;
+ return p;
+ }
+ }
+
+ public void setViewPosition(Point p)
+ {
+ Component view = getView();
+ if (view != null)
+ {
+ Point q = new Point(-p.x, -p.y);
+ view.setLocation(q);
+ fireStateChanged();
+ }
+ }
+
+ public Rectangle getViewRect()
+ {
+ return new Rectangle(getViewPosition(),
+ getExtentSize());
+ }
+
+ /**
+ * @deprecated 1.4
+ */
+ public boolean isBackingStoreEnabled()
+ {
+ return scrollMode == BACKINGSTORE_SCROLL_MODE;
+ }
+
+ /**
+ * @deprecated 1.4
+ */
+ public void setBackingStoreEnabled(boolean b)
+ {
+ if (b && scrollMode != BACKINGSTORE_SCROLL_MODE)
+ {
+ scrollMode = BACKINGSTORE_SCROLL_MODE;
+ fireStateChanged();
+ }
+ }
+
+ public void setScrollMode(int mode)
+ {
+ scrollMode = mode;
+ fireStateChanged();
+ }
+
+ public int getScrollMode()
+ {
+ return scrollMode;
+ }
+
+ public Component getView()
+ {
+ if (getComponentCount() == 0)
+ return null;
+
+ return getComponents()[0];
+ }
+
+ public void setView(Component v)
+ {
+ while (getComponentCount() > 0)
+ {
+ if (viewListener != null)
+ getView().removeComponentListener(viewListener);
+ remove(0);
+ }
+
+ if (v != null)
+ {
+ if (viewListener == null)
+ viewListener = createViewListener();
+ v.addComponentListener(viewListener);
+ add(v);
+ fireStateChanged();
+ }
+ }
+
+ public void revalidate()
+ {
+ fireStateChanged();
+ super.revalidate();
+ }
+
+ public void reshape(int x, int y, int w, int h)
+ {
+ boolean changed =
+ (x != getX())
+ || (y != getY())
+ || (w != getWidth())
+ || (h != getHeight());
+ super.reshape(x, y, w, h);
+ if (changed)
+ fireStateChanged();
+ }
+
+ protected void addImpl(Component comp, Object constraints, int index)
+ {
+ if (getComponentCount() > 0)
+ remove(getComponents()[0]);
+
+ super.addImpl(comp, constraints, index);
+ }
+
+ public final Insets getInsets()
+ {
+ return new Insets(0,0,0,0);
+ }
+
+ public final Insets getInsets(Insets insets)
+ {
+ if (insets == null)
+ return getInsets();
+ insets.top = 0;
+ insets.bottom = 0;
+ insets.left = 0;
+ insets.right = 0;
+ return insets;
+ }
+
+ public boolean isOptimizedDrawingEnabled()
+ {
+ return false;
+ }
+
+ public void paint(Graphics g)
+ {
+ paintComponent(g);
+ }
+
+ public void addChangeListener(ChangeListener listener)
+ {
+ listenerList.add(ChangeListener.class, listener);
+ }
+
+ public void removeChangeListener(ChangeListener listener)
+ {
+ listenerList.remove(ChangeListener.class, listener);
+ }
+
+ public ChangeListener[] getChangeListeners()
+ {
+ return (ChangeListener[]) getListeners(ChangeListener.class);
+ }
+
+ protected void fireStateChanged()
+ {
+ ChangeListener[] listeners = getChangeListeners();
+ for (int i = 0; i < listeners.length; ++i)
+ listeners[i].stateChanged(changeEvent);
+ }
+
+ /**
+ * This method returns the String ID of the UI class of Separator.
+ *
+ * @return The UI class' String ID.
+ */
+ public String getUIClassID()
+ {
+ return "ViewportUI";
+ }
+
+ /**
+ * This method resets the UI used to the Look and Feel defaults..
+ */
+ public void updateUI()
+ {
+ setUI((ViewportUI) UIManager.getUI(this));
+ }
+
+ /**
+ * This method returns the viewport's UI delegate.
+ *
+ * @return The viewport's UI delegate.
+ */
+ public ViewportUI getUI()
+ {
+ return (ViewportUI) ui;
+ }
+
+ /**
+ * This method sets the viewport's UI delegate.
+ *
+ * @param ui The viewport's UI delegate.
+ */
+ public void setUI(ViewportUI ui)
+ {
+ super.setUI(ui);
+ }
+
+ public final void setBorder(Border border)
+ {
+ if (border != null)
+ throw new IllegalArgumentException();
+ }
+
+ /**
+ * Creates a {@link ViewListener} that is supposed to listen for
+ * size changes on the view component.
+ *
+ * @return a ViewListener instance
+ */
+ protected ViewListener createViewListener()
+ {
+ return new ViewListener();
+ }
+
+ /**
+ * Creates the LayoutManager that is used for this viewport. Override
+ * this method if you want to use a custom LayoutManager.
+ *
+ * @return a LayoutManager to use for this viewport
+ */
+ protected LayoutManager createLayoutManager()
+ {
+ return new ViewportLayout();
+ }
+}