# Touchscreen-Scrollen, wo liegt der Fehler?



## NintendoLink07 (29. Feb 2012)

Hallo,

Momentan bin ich dabei ein Java-Programm, welches von "Haus aus" nur mit *Scrollbar* zu scrollen ist, mit einem Touchscrollen auszustatten.

Und da ja die Finger- bzw. Stiftberührungen im Prinzip auch nur Mauseingaben sind, habe ich das ganze mit *MouseListener* bzw. eher mit *MouseMotionListener* programmiert.

An sich funktioniert das Programm gut, nur leider finde ich keine Lösung für mein Problem, welcher sich auf das scrollen bezieht.

Die *Scrollbars* springen automatisch zu dem Punkt, wo sich das *MouseEvent* befindet, was sie aber nicht tun sollen.
Die *Scrollbars* sollten sich um den Punkt "drehen".
Das heißt: Wenn ich auf Punkt 340|480 klicke, soll sich der aktuelle "Bildschirm" um den Punkt drehen.

Das Hintergrundbild, über welches gescrollt werden soll, befindet sich im Anhang.
Aber am besten ihr benutzt ein Bild von euch, da ich dieses hier kleiner skalieren musste, damit es überhaupt hochgeladen werden konnte.
Hauptsache ist, dass der Sinn klar wird.

Nun folgt der Java-Code:


```
import java.awt.event.AdjustmentListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.awt.Container;
import java.awt.Color;

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.ImageIcon;

import javax.imageio.ImageIO;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.File;

public class OPPJ_Up
extends JApplet
{
	public JScrollPane jsp; //Scrollfeld
	public JScrollBar hBar; //horizonzale Scrollbar
	public JScrollBar vBar; //vertikale Scrollbar
	public JLabel jlbx;
	public JLabel jlby;

	public BufferedImage image; //Das gepufferte Bild für den Hintergrund

	public ImageIcon icon; //Das gepufferte Bild in einem ImageIcon, um das Bild scrollbar zu machen

	public AdjustmentListener hListener;
	public AdjustmentListener vListener;

	public int ZielX = 0;
	public int ZielY = 0;

	public void init() //Dieser Teil des Applets wird beim Start initialisiert
	{
		setSize(600,600);
			//Nun folgt eine Try-Catch-Klausel,in welcher das Bild
			//eingelesen wird und anschließend in die Methode für das Zeichnen
			//übergeben wird.
			//Sofern Fehler auftreten, wird die Fehlermeldung in das DOS-Fenster
			//übergeben.
		try
		{
			this.image = ImageIO.read(new File("01_Hauptebene.jpg"));
		}
		catch(IOException e){System.err.println(e.toString());}

		icon = new ImageIcon(image);

			//Nun wird der Container für das Applet initialisiert
		Container cp = getContentPane();

			//Hier wird das JLabel für die X-Achse initialisiert und der Text des Labels gesetzt
			//Zusätzlich die Location und die Size
		jlbx = new JLabel("X-Achse:  ");
		jlbx.setLocation(450,10);
		jlbx.setSize(200,10);
		jlbx.setForeground(Color.red);
		cp.add(jlbx);

			//Hier wird das JLabel für die Y-Achse initialisiert und der Text des Labels gesetzt
			//Zusätzlich die Location und die Size
		jlby = new JLabel("Y-Achse:  ");
		jlby.setLocation(450,25);
		jlby.setSize(200,10);
		jlby.setForeground(Color.red);
		cp.add(jlby);

			//Hier wird die ScrollPane, welches für das
			//scrollen des Bildes zuständig ist, initialisiert
      	jsp = new JScrollPane(new JLabel(icon));

			//Im Folgenden wird der AdjustmentListener
			//für die horizontale Scrollbar initialisiert
      	hListener = new AdjustmentListener()
      	{
			public void adjustmentValueChanged(AdjustmentEvent e)
			{
				jlbx.setVisible(false);jlbx.setVisible(true);
				jlby.setVisible(false);jlby.setVisible(true);
			}
		};
			//Jetzt wird die horizontale Scrollbar initialisiert
			//Und anschließend der AdjustmentListener hinzugefügt
		hBar = jsp.getHorizontalScrollBar();
		hBar.addAdjustmentListener(hListener);

			//Im Folgenden wird der AdjustmentListener
			//für die vertikale Scrollbar initialisiert
		vListener = new AdjustmentListener()
		{
			public void adjustmentValueChanged(AdjustmentEvent e)
			{
				jlbx.setVisible(false);jlbx.setVisible(true);
				jlby.setVisible(false);jlby.setVisible(true);
			}
		};
			//Jetzt wird die vertikale Scrollbar initialisiert
			//Und anschließend der AdjustmentListener hinzugefügt
		vBar = jsp.getVerticalScrollBar();
		vBar.addAdjustmentListener(vListener);

		jsp.addMouseListener(new MyMouseListener());
		jsp.addMouseMotionListener(new MyMouseMotionListener());

			//Nun wird die ScrollPane an den Container hinzugefügt
    	cp.add(jsp);
  	}


	int yWert = 0;
	int xWert = 0;
	int i = 0;

	public int speichern(int yWert)
	{
		return yWert;
	}

	public class MyMouseListener
	implements MouseListener
	{
		public void mousePressed(MouseEvent e)
		{
		}

		public void mouseReleased(MouseEvent e)
		{
			System.out.println(yWert);
		}

		public void mouseEntered(MouseEvent e)
		{
		}

		public void mouseExited(MouseEvent e)
		{
		}

		public void mouseClicked(MouseEvent e)
		{
		}
	}

	public class MyMouseMotionListener
	implements MouseMotionListener
	{
		public void mouseMoved(MouseEvent e)
		{
		}

		public void mouseDragged(MouseEvent e)
		{
			jlbx.setText("X-Achse:  "+e.getX());
			jlby.setText("Y-Achse:  "+e.getY());

			if(i == 0)
			{
				yWert = e.getY()-ZielY;
				xWert = e.getX()-ZielX;
				i++;
			}
			else
			{
				yWert = e.getY();
				xWert = e.getX();
			}


			//System.out.println("\n"+e.getY()+"//"+ZielY);
			//System.out.println("\n"+e.getX()+"//"+ZielX);

			if(getHeight() - ZielY > e.getY()-ZielY)
			{
				//System.out.println("Momentaner Bereich, von Y:"+ZielY+" :"+yWert);
				vBar.setValue(yWert);
				yWert = vBar.getValue();
			}

			if(getWidth() - ZielX > e.getX()-ZielX)
			{
				//System.out.println("Momentaner Bereich, von X:"+ZielX+" :"+xWert);
				hBar.setValue(xWert);
				xWert = hBar.getValue();
			}
		}
	}

} //Ende von: public class OPPJ_Up
```


----------



## Ebenius (29. Feb 2012)

Ich bin nicht ganz sicher; suchst Du soetwas? Diese JXScrollPane scrollt wenn man die rechte Maustaste drückt. Das kannst Du Dir sicher ganz leicht anpassen:


```
/* $Id: JXScrollPane.java,v 1.3 2009/02/10 14:55:00 ebenius Exp $ */

/* Copyright 2009 Sebastian Haufe

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       [url]http://www.apache.org/licenses/LICENSE-2.0[/url]

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

package com.ebenius.widget;

import static java.awt.AWTEvent.MOUSE_EVENT_MASK;
import static java.awt.AWTEvent.MOUSE_MOTION_EVENT_MASK;
import static java.awt.event.InputEvent.BUTTON3_DOWN_MASK;
import static java.awt.event.MouseEvent.MOUSE_DRAGGED;
import static java.awt.event.MouseEvent.MOUSE_PRESSED;
import static java.awt.event.MouseEvent.MOUSE_RELEASED;

import java.awt.*;
import java.awt.event.AWTEventListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;

/**
 * A {@link JScrollPane} derivate, enhanced by mouse dragging support.
 * 
 * @see #isViewDraggingEnabled()
 * @see #isHorizontalViewDraggingEnabled()
 * @see #isVerticalViewDraggingEnabled()
 * @version $Revision: 1.3 $ as of $Date: 2009/02/10 14:55:00 $
 * @author Sebastian Haufe
 */
public class JXScrollPane extends JScrollPane {

  /** Serial version UID */
  private static final long serialVersionUID = 4240385570313149664L;
  private static ToolkitMouseListener multiListener = null;

  // -------------------------------------------------------------------------
  // Instance fields
  // -------------------------------------------------------------------------

  private Point draggingFrom;
  private int viewDragModifierMask = BUTTON3_DOWN_MASK;
  private boolean horizontalViewDraggingEnabled = true;
  private boolean verticalViewDraggingEnabled = true;

  // -------------------------------------------------------------------------
  // Constructors
  // -------------------------------------------------------------------------

  /**
   * Creates an empty (no viewport view) <code>JXScrollPane</code> where both
   * horizontal and vertical scrollbars appear when needed.
   */
  public JXScrollPane() {
    super();
    enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
    enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  }

  /**
   * Creates a <code>JXScrollPane</code> that displays the view component in a
   * viewport whose view position can be controlled with a pair of scrollbars.
   * The scrollbar policies specify when the scrollbars are displayed, For
   * example, if <code>vsbPolicy</code> is
   * <code>VERTICAL_SCROLLBAR_AS_NEEDED</code> then the vertical scrollbar
   * only appears if the view doesn't fit vertically. The available policy
   * settings are listed at {@link #setVerticalScrollBarPolicy} and
   * {@link #setHorizontalScrollBarPolicy}.
   * 
   * @see #setViewportView
   * @param view the component to display in the scrollpane's viewport
   * @param vsbPolicy an integer that specifies the vertical scrollbar policy
   * @param hsbPolicy an integer that specifies the horizontal scrollbar
   *          policy
   */
  public JXScrollPane(Component view, int vsbPolicy, int hsbPolicy) {
    super(view, vsbPolicy, hsbPolicy);
    enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
    enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  }

  /**
   * Creates a <code>JXScrollPane</code> that displays the contents of the
   * specified component, where both horizontal and vertical scrollbars appear
   * whenever the component's contents are larger than the view.
   * 
   * @see #setViewportView
   * @param view the component to display in the scrollpane's viewport
   */
  public JXScrollPane(Component view) {
    super(view);
    enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
    enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  }

  /**
   * Creates an empty (no viewport view) <code>JXScrollPane</code> with
   * specified scrollbar policies. The available policy settings are listed at
   * {@link #setVerticalScrollBarPolicy} and
   * {@link #setHorizontalScrollBarPolicy}.
   * 
   * @see #setViewportView
   * @param vsbPolicy an integer that specifies the vertical scrollbar policy
   * @param hsbPolicy an integer that specifies the horizontal scrollbar
   *          policy
   */
  public JXScrollPane(int vsbPolicy, int hsbPolicy) {
    super(vsbPolicy, hsbPolicy);
    enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);
    enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  }

  // -------------------------------------------------------------------------
  // Viewport dragging support
  // -------------------------------------------------------------------------

  /**
   * Determines whether the view is draggable based on the given mouse event.
   * This implementation checks whether {@link #isViewDraggingEnabled()
   * dragging is enabled} and the {@link #getViewDragModifierMask()} matches
   * the {@link MouseEvent#getModifiersEx() modifiers} of the given mouse
   * event.
   * <p>
   * The method is being called on {@link MouseEvent MOUSE_PRESSED} and
   * {@link MouseEvent#MOUSE_DRAGGED} events to check whether the event is
   * used or dismissed for view dragging.
   * 
   * @param e the mouse event to inspect
   * @return {@code true} if the mouse event is a view drag trigger
   */
  protected boolean isViewDraggable(MouseEvent e) {
    final int mask = viewDragModifierMask;
    return isViewDraggingEnabled() && (mask & e.getModifiersEx()) == mask;
  }

  /**
   * Determines whether the given point is in the viewport of {@code this}
   * scroll pane.
   * 
   * @param point the point to check
   * @return {@code true} if the point is on the viewport
   */
  protected boolean viewportContainsPoint(Point point) {
    return getViewport().getBounds().contains(point);
  }

  /**
   * Start dragging the view with the given mouse event.
   * 
   * @param e the mouse event
   */
  protected void startDraggingView(MouseEvent e) {
    draggingFrom = e.getPoint();
    setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
    multiListener.setCurrentDraggingSlave(this);
  }

  /**
   * Stop dragging the view with the given mouse event.
   * 
   * @param e the mouse event
   */
  protected void stopDraggingView(MouseEvent e) {
    multiListener.setCurrentDraggingSlave(null);
    draggingFrom = null;
    setCursor(null);
  }

  /**
   * Drag the view according to the given mouse event.
   * 
   * @param e the mouse event
   */
  protected void dragView(MouseEvent e) {
    final JViewport viewport = getViewport();
    final Component view = viewport.getView();
    final Point from;

    /* currently not dragging or no viewport view; get out-a-here */
    if ((from = draggingFrom) == null || view == null) {
      return;
    }

    /* the amount of dragging */
    final Point to = e.getPoint();
    int dx = isHorizontalViewDraggingEnabled() ? from.x - to.x : 0;
    int dy = isVerticalViewDraggingEnabled() ? from.y - to.y : 0;

    // /* accelerate by the unit increment */
    // if (view instanceof Scrollable) {
    // final Scrollable scrollable = (Scrollable) view;
    // final Rectangle viewRect = viewport.getViewRect();
    // dx *= scrollable.getScrollableUnitIncrement(viewRect, dx, HORIZONTAL);
    // dy *= scrollable.getScrollableUnitIncrement(viewRect, dy, VERTICAL);
    // }

    /* calculate the new view position */
    final Point viewPos = viewport.getViewPosition();
    final Dimension viewSize = viewport.getViewSize();
    final Dimension extentSize = viewport.getExtentSize();
    final int maxViewPosX = viewSize.width - extentSize.width;
    final int maxViewPosY = viewSize.height - extentSize.height;
    viewPos.x = Math.max(0, Math.min(viewPos.x + dx, maxViewPosX));
    viewPos.y = Math.max(0, Math.min(viewPos.y + dy, maxViewPosY));

    /* move the view and repaint the viewport */
    viewport.setViewPosition(viewPos);
    viewport.repaint();
    draggingFrom = to;
  }

  // -------------------------------------------------------------------------
  // Event dispatching
  // -------------------------------------------------------------------------

  @Override
  protected void processMouseEvent(MouseEvent e) {
    super.processMouseEvent(e);
    processDragEvent(e);
  }

  @Override
  protected void processMouseMotionEvent(MouseEvent e) {
    super.processMouseMotionEvent(e);
    processDragEvent(e);
  }

  protected void processDragEvent(MouseEvent e) {
    switch (e.getID()) {
    case MOUSE_DRAGGED:
      if (draggingFrom != null && !e.isConsumed() && isViewDraggable(e)) {
        dragView(e);
      }
      break;
    case MOUSE_RELEASED:
      stopDraggingView(e);
      break;
    case MOUSE_PRESSED:
      if (!e.isConsumed()
            && isViewDraggable(e)
            && viewportContainsPoint(e.getPoint())) {
        startDraggingView(e);
      }
      break;
    }
  }

  // -------------------------------------------------------------------------
  // Child listener support
  // -------------------------------------------------------------------------

  @Override
  public void addNotify() {
    synchronized (ToolkitMouseListener.class) {
      if (multiListener == null) {
        multiListener = new ToolkitMouseListener();
      }
      multiListener.addSlave(this);
    }

    super.addNotify();
  }

  @Override
  public void removeNotify() {
    super.removeNotify();

    synchronized (ToolkitMouseListener.class) {
      if (multiListener != null && !multiListener.removeSlave(this)) {
        multiListener = null;
      }
    }
  }

  // -------------------------------------------------------------------------
  // Bean getters and setters
  // -------------------------------------------------------------------------

  /**
   * Returns the modifier mask to be checked for triggering view drag support.
   * By default, this is the {@link InputEvent#BUTTON3_DOWN_MASK}.
   * 
   * @return the modifier mask
   */
  public int getViewDragModifierMask() {
    return viewDragModifierMask;
  }

  /**
   * Sets the modifier mask to be checked for triggering view drag support. By
   * default, this is the {@link InputEvent#BUTTON3_DOWN_MASK}.
   * 
   * @param modifierMask the modifier mask to set
   */
  public void setViewDragModifierMask(int modifierMask) {
    final int old = this.viewDragModifierMask;
    this.viewDragModifierMask = modifierMask;
    firePropertyChange("viewDragModifierMask", //$NON-NLS-1$
          old, viewDragModifierMask);
  }

  /**
   * Determines whether {@code this} scroll pane's view dragging is enabled in
   * at least one direction. Defaults to {@code true}.
   * 
   * @return {@code true} if view dragging is enabled
   * @see #isHorizontalViewDraggingEnabled()
   * @see #isVerticalViewDraggingEnabled()
   */
  public boolean isViewDraggingEnabled() {
    return horizontalViewDraggingEnabled || verticalViewDraggingEnabled;
  }

  /**
   * Determines whether {@code this} scroll pane's view dragging is enabled in
   * horizontal direction. Defaults to {@code true}.
   * 
   * @return {@code true} if horizontal view dragging is enabled
   */
  public boolean isHorizontalViewDraggingEnabled() {
    return horizontalViewDraggingEnabled;
  }

  /**
   * Sets whether {@code this} scroll pane's horizontal view dragging is
   * enabled. Defaults to {@code true}.
   * 
   * @param enabled {@code true} to enable view dragging horizontally
   */
  public void setHorizontalViewDraggingEnabled(boolean enabled) {
    final boolean old = this.horizontalViewDraggingEnabled;
    this.horizontalViewDraggingEnabled = enabled;
    firePropertyChange("horizontalViewDraggingEnabled", //$NON-NLS-1$
          old, horizontalViewDraggingEnabled);
  }

  /**
   * Determines whether {@code this} scroll pane's view dragging is enabled in
   * vertical direction. Defaults to {@code true}.
   * 
   * @return {@code true} if vertical view dragging is enabled
   */
  public boolean isVerticalViewDraggingEnabled() {
    return verticalViewDraggingEnabled;
  }

  /**
   * Sets whether {@code this} scroll pane's vertical view dragging is
   * enabled. Defaults to {@code true}.
   * 
   * @param enabled {@code true} to enable view dragging vertically
   */
  public void setVerticalViewDraggingEnabled(boolean enabled) {
    final boolean old = this.verticalViewDraggingEnabled;
    this.verticalViewDraggingEnabled = enabled;
    firePropertyChange("horizontalViewDraggingEnabled", //$NON-NLS-1$
          old, verticalViewDraggingEnabled);
  }

  // -------------------------------------------------------------------------
  // Inner classes
  // -------------------------------------------------------------------------

  private static class ToolkitMouseListener implements AWTEventListener {

    private final Set<JXScrollPane> slaves = new HashSet<JXScrollPane>();
    private JXScrollPane currentDraggingSlave = null;

    /** Creates a new {@code ToolkitMouseListener}. */
    public ToolkitMouseListener() {}

    public void eventDispatched(AWTEvent e) {
      final JXScrollPane slave = currentDraggingSlave;
      switch (e.getID()) {
      case MOUSE_DRAGGED:
        if (slave != null) {
          slave.processDragEvent(convertMouseEvent((MouseEvent) e, slave));
        }
        break;
      case MOUSE_RELEASED:
        if (slave != null) {
          slave.stopDraggingView(convertMouseEvent((MouseEvent) e, slave));
        }
        break;
      case MOUSE_PRESSED:
        redispatchDragEvent((MouseEvent) e);
        break;
      default:
        return;
      }
    }

    private void redispatchDragEvent(MouseEvent e) {
      final Component src = (Component) e.getSource();
      for (Component c = src.getParent(); c != null; c = c.getParent()) {
        if (c instanceof JXScrollPane) {
          ((JXScrollPane) c).processDragEvent(convertMouseEvent(e, c));
          break;
        }
      }
    }

    private MouseEvent convertMouseEvent(
          MouseEvent e,
          Component targetComponent) {
      return SwingUtilities.convertMouseEvent((Component) e.getSource(), e,
            targetComponent);
    }

    void addSlave(JXScrollPane slave) {
      synchronized (ToolkitMouseListener.class) {
        slaves.add(slave);
        if (slaves.size() == 1) {
          slave.getToolkit().addAWTEventListener(this, MOUSE_EVENT_MASK);
        }
      }
    }

    boolean removeSlave(JXScrollPane slave) {
      synchronized (ToolkitMouseListener.class) {
        slaves.remove(slave);
        final boolean hasMoreSlaves = !slaves.isEmpty();
        if (!hasMoreSlaves) {
          slave.getToolkit().removeAWTEventListener(this);
        }
        return hasMoreSlaves;
      }
    }

    void setCurrentDraggingSlave(JXScrollPane slave) {
      synchronized (ToolkitMouseListener.class) {
        final JXScrollPane oldSlave = currentDraggingSlave;
        final Toolkit tk;
        long mask;
        if (slave != null) {
          tk = slave.getToolkit();
          mask = MOUSE_EVENT_MASK | MOUSE_MOTION_EVENT_MASK;
        } else if (oldSlave != null) {
          tk = oldSlave.getToolkit();
          mask = MOUSE_EVENT_MASK;
        } else {
          return;
        }

        tk.removeAWTEventListener(this);
        tk.addAWTEventListener(this, mask);
        this.currentDraggingSlave = slave;
      }
    }
  }
}
```

Ebenius


----------



## NintendoLink07 (29. Feb 2012)

Sorry, da ich erst seit gut 1 1/2 Jahren Java programmiere, komm' ich noch nicht so ganz durch dein Programm durch.
Ich mein, die meisten Schlüsselwörter kenn' ich, aber trotzdem ist das, glaube ich, noch zu hoch für mich.


----------



## bERt0r (1. Mrz 2012)

Du merkst dir bei mousePressed den Punkt in einer Variable. Ausserdem noch den Punkt den dir mouseDragged liefert. In mouseDragged kannst du am ende repaint aufrufen.

In deiner paintComponent rechnest du dir die Differenz deiner zwei Punkte aus - also einen Vektor. Diesen Vektor kannst du dann mit einem AffineTransform#translate auf dein Graphics anwenden.

```
class DragPanel extends JPanel
	{
		BufferedImage image;
		Point from,to;
		Point location=new Point(0,0);
		int dx,dy;
		DragPanel()
		{
			super();
			
			try
			{
				image = ImageIO.read(new URL("http://www.java-forum.org/images/misc/java_forum_org.gif"));
			} catch (MalformedURLException e)
			{
				e.printStackTrace();
			} catch (IOException e)
			{
				e.printStackTrace();
			}
			
			MouseAdapter dragAdapter=new MouseAdapter()
			{
				@Override
				public void mousePressed(MouseEvent e)
				{
					from=e.getPoint();
				}
				@Override
				public void mouseDragged(MouseEvent e)
				{
					to=e.getPoint();
					dx=from.x-to.x;
					dy=from.y-to.y;
					repaint();
				}
				@Override
				public void mouseReleased(MouseEvent e)
				{
					location.translate(dx, dy);
					dx=0;
					dy=0;
					repaint();
				}
			};
			
			this.addMouseListener(dragAdapter);
			this.addMouseMotionListener(dragAdapter);
		}
		
		@Override
		public void paintComponent(Graphics g)
		{
			AffineTransform af=AffineTransform.getTranslateInstance(dx, dy);
			Graphics2D g2=(Graphics2D)g;
			g2.setColor(this.getBackground());
			g2.fill(g2.getClip());
			g2.setTransform(af);
			g2.drawImage(image,location.x,location.y,null);
		}
	}
```


----------

