在填充绘制形状的JPanel上抓取并拖动滚动

时间:2011-04-18 17:14:03

标签: java swing jpanel

好的,所以我让这个JPanel填充了钻石形状的20 x 20六边形。它们非常大,所以你无法同时看到所有这些,但由于这应该是游戏中的地图,我想抓住滚动。

实际的移动工作 - 但是当我移动面板时,我只移动我已经可以看到的瓷砖,应该在窗口边框外面的瓷砖不显示。就像我在移动图像一样。但是,如果我调整窗口大小,我会看到更多的六边形。

我已经尝试在mouseDragged完成后强制重绘,但没有成功。 任何有任何想法的人都非常欢迎分享!

这是我在Interface-class中显示所有内容的地方:

            ComponentMover comp = new ComponentMover();
        comp.registerComponent(gameTiles,this);
        main.add(gameTiles, "Game");
        cardLayout.show(main, "Game");

这是ComponentMover类(从http://tips4java.wordpress.com/2009/06/14/moving-windows/借用一些mods)

公共类ComponentMover扩展了MouseAdapter {

private Class destinationClass;
private Component destinationComponent;
private Component destination;
private Component source;

private ArrayList<Component>comps;

private boolean changeCursor = true;

private Point pressed;
private Point location;

private Cursor originalCursor;
private boolean autoscrolls;

private Insets dragInsets = new Insets(0, 0, 0, 0);
private Dimension snapSize = new Dimension(1, 1);

/**
 *  Constructor for moving individual components. The components must be
 *  regisetered using the registerComponent() method.
 */
public ComponentMover()
{ comps = new ArrayList<Component>();
}

/**
 *  Constructor to specify a Class of Component that will be moved when
 *  drag events are generated on a registered child component. The events
 *  will be passed to the first ancestor of this specified class.
 *
 *  @param destinationClass  the Class of the ancestor component
 *  @param component         the Components to be registered for forwarding
 *                           drag events to the ancestor Component.
 */
public ComponentMover(Class destinationClass, Component... components)
{
    this.destinationClass = destinationClass;
    registerComponent( components );
}

/**
 *  Constructor to specify a parent component that will be moved when drag
 *  events are generated on a registered child component.
 *
 *  @param destinationComponent  the component drage events should be forwareded to
 *  @param components    the Components to be registered for forwarding drag
 *                       events to the parent component to be moved
 */
public ComponentMover(Component destinationComponent, Component... components)
{
    this.destinationComponent = destinationComponent;
    registerComponent( components );
}

/**
 *  Get the change cursor property
 *
 *  @return  the change cursor property
 */
public boolean isChangeCursor()
{
    return changeCursor;
}

/**
 *  Set the change cursor property
 *
 *  @param  changeCursor when true the cursor will be changed to the
 *                       Cursor.MOVE_CURSOR while the mouse is pressed
 */
public void setChangeCursor(boolean changeCursor)
{
    this.changeCursor = changeCursor;
}

/**
 *  Get the drag insets
 *
 *  @return  the drag insets
 */
public Insets getDragInsets()
{
    return dragInsets;
}

/**
 *  Set the drag insets. The insets specify an area where mouseDragged
 *  events should be ignored and therefore the component will not be moved.
 *  This will prevent these events from being confused with a
 *  MouseMotionListener that supports component resizing.
 *
 *  @param  dragInsets
 */
public void setDragInsets(Insets dragInsets)
{
    this.dragInsets = dragInsets;
}

/**
 *  Remove listeners from the specified component
 *
 *  @param component  the component the listeners are removed from
 */
public void deregisterComponent(Component... components)
{
    for (Component component : components)
        component.removeMouseListener( this );
}

/**
 *  Add the required listeners to the specified component
 *
 *  @param component  the component the listeners are added to
 */
public void registerComponent(Component... components)
{
    for (Component component : components) {
        component.addMouseListener( this );
        comps.add(component);
    }
}

/**
 *  Get the snap size
 *
 *  @return the snap size
 */
public Dimension getSnapSize()
{
    return snapSize;
}

/**
 *  Set the snap size. Forces the component to be snapped to
 *  the closest grid position. Snapping will occur when the mouse is
 *  dragged half way.
 */
public void setSnapSize(Dimension snapSize)
{
    this.snapSize = snapSize;
}

/**
 *  Setup the variables used to control the moving of the component:
 *
 *  source - the source component of the mouse event
 *  destination - the component that will ultimately be moved
 *  pressed - the Point where the mouse was pressed in the destination
 *      component coordinates.
 */
@Override
public void mousePressed(MouseEvent e)
{
    source = e.getComponent();
    int width  = source.getSize().width  - dragInsets.left - dragInsets.right;
    int height = source.getSize().height - dragInsets.top - dragInsets.bottom;
    Rectangle r = new Rectangle(dragInsets.left, dragInsets.top, width, height);

    if (r.contains(e.getPoint()))
        setupForDragging(e);
}

private void setupForDragging(MouseEvent e)
{
    source.addMouseMotionListener( this );

    //  Determine the component that will ultimately be moved

    if (destinationComponent != null)
    {
        destination = destinationComponent;
    }
    else if (destinationClass == null)
    {
        destination = source;
    }
    else  //  forward events to destination component
    {
        destination = SwingUtilities.getAncestorOfClass(destinationClass, source);
    }

    pressed = e.getLocationOnScreen();
    location = destination.getLocation();

    if (changeCursor)
    {
        originalCursor = source.getCursor();
        source.setCursor( Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR) );
    }

    //  Making sure autoscrolls is false will allow for smoother dragging of
    //  individual components

    if (destination instanceof JComponent)
    {
        JComponent jc = (JComponent)destination;
        autoscrolls = jc.getAutoscrolls();
        jc.setAutoscrolls( false );
    }
}

/**
 *  Move the component to its new location. The dragged Point must be in
 *  the destination coordinates.
 */
@Override
public void mouseDragged(MouseEvent e)
{
    destination.repaint();
    Point dragged = e.getLocationOnScreen();
    int dragX = getDragDistance(dragged.x, pressed.x, snapSize.width);
    int dragY = getDragDistance(dragged.y, pressed.y, snapSize.height);
    destination.setLocation(location.x + dragX, location.y + dragY);
    for(Component c : comps)
        c.repaint();
}

/*
 *  Determine how far the mouse has moved from where dragging started
 *  (Assume drag direction is down and right for positive drag distance)
 */
private int getDragDistance(int larger, int smaller, int snapSize)
{
    int halfway = snapSize / 2;
    int drag = larger - smaller;
    drag += (drag < 0) ? -halfway : halfway;
    drag = (drag / snapSize) * snapSize;

    return drag;
}

/**
 *  Restore the original state of the Component
 */
@Override
public void mouseReleased(MouseEvent e)
{
    for(Component c : comps)
        c.repaint();
    System.out.println("Repainted!");

    source.removeMouseMotionListener( this );

    if (changeCursor)
        source.setCursor( originalCursor );

    if (destination instanceof JComponent)
    {
        ((JComponent)destination).setAutoscrolls( autoscrolls );
    }

}

}

1 个答案:

答案 0 :(得分:1)

ComponentMover用于更改面板上组件的位置。

听起来我想要滚动滚动窗格视口中包含的面板。如果是这样,我建议您查看JComponent.setAutoScrolls()方法,该方法有一些用于在滚动窗格中滚动组件的示例代码。