Схожу с ума с этими методами mouseEvent в Java - PullRequest
3 голосов
/ 02 марта 2010

Неделя в этом, и я просто бьюсь головой об эту проблему. Это должно быть простое упражнение:

У меня есть прямоугольник. Я щелкаю и перетаскиваю прямоугольник на оси х. Прямоугольник должен перемещаться только в пределах заданной ограничивающей области (холста), поэтому, если ширина холста составляет 200 пикселей, координата x должна изменяться только от 0 до getWidth()-RECTANGLE_WIDTH.

Достаточно просто, но я просто не могу заставить эту чертову вещь работать.

Ниже приведен мой громоздкий код.

Я прикрепил два GLabels для просмотра координат. Я заметил, что метка mouseMoved будет отображать только координаты внутри холста (что я хочу), но метка mouseDragged будет иметь отрицательный характер, а также будет отображать координаты за пределами холста - это также место, где контролируется движение объекта прямоугольника. Я не уверен, почему эти два поведения отличаются.

Прямо сейчас, мое заявление ниже:

if ((gobj.getX()) > 0 && (gobj.getX()) < (APPLICATION_WIDTH - PADDLE_WIDTH)){
     gobj.move(e.getX() - lastX, 0);                
} 

то, что до сих пор делает этот оператор, - это получить прямоугольник к краю, но затем он просто остается там и не возвращается. Я дергаю себя за эту штуку ...

import java.awt.*;
import java.awt.event.*;
import acm.graphics.*;
import acm.program.*;

/** This class displays a mouse-draggable rectangle and oval */

public class DragObject extends GraphicsProgram {

private static final int PADDLE_WIDTH = 150;
public static final int APPLICATION_WIDTH = 700;

    public void run() {

        GRect rect = new GRect(100, 100, 150, 100);
        rect.setFilled(true);
        rect.setColor(Color.RED);   
        add(rect);

        label2 = new GLabel ("");
        add(label2, 300, 400);


        label = new GLabel ("");
        add(label, 300, 300);
        addMouseListeners();


    }

    /* these coordinates are never going beyond the canvas-even if the 
     * mouse does...this is good...i want this   */

    public void mouseMoved(MouseEvent e){

        label2.setLabel("Coordinates:" + e.getX() + ", " + e.getY());

    }

/** Called on mouse press to record the coordinates of the click */
    public void mousePressed(MouseEvent e) {
        lastX = e.getX();
        lastY = e.getY();
        gobj = getElementAt(lastX, lastY);

    }

/** Called on mouse drag to reposition the object */
    public void mouseDragged(MouseEvent e) { 

          if ((gobj.getX()) > 0 && (gobj.getX()) < (APPLICATION_WIDTH - PADDLE_WIDTH)){
            gobj.move(e.getX() - lastX, 0);

           } 

            lastX = e.getX();


            /* This label is active when i click the object, and does go into negative 
             * numbers and still counts even when off the canvas...*/
            label.setLabel("Coordinates:" + e.getX() + ", " + e.getY());
    }

/* Instance variables */

private GLabel label2;
private GLabel label;
private GObject gobj;   /* The object being dragged */
private double lastX;   /* The last mouse X position */
private double lastY;   /* The last mouse Y position */
}

1 Ответ

3 голосов
/ 02 марта 2010

Вы можете перетаскивать из компонента, даже из окна, вполне умышленно, чтобы поддерживать перетаскивание.

Для событий перетаскивания вам просто нужно ограничить местоположение события внутри его контейнера:

static public final int MAX_X=(CANVAS_WIDTH - PADDLE_WIDTH);

...

public void mouseDragged(MouseEvent e) { 
    int px=Math.max(0,Math.min(e.getX(),MAX_X));
    int dx=(px-lastX);

    if(dx!=0) { 
        gobj.move(dx); 
        lastX=px;
        }
    }

После сна и перечитывания комментариев у меня есть идея, в чем может заключаться проблема - в предоставленном коде GObject не отображается, как и как он создается / инициализируется. Поэтому трудно догадаться о контексте кода в вопросе.

Держу пари, что весло создано изначально в середине (возможно, в середине / внизу) холста. Приведенный выше код и вопрос только ограничивают дельту, чтобы предотвратить превышение дельтой границ холста - она ​​не учитывает начальную позицию весла. То есть, если весло начинается при x = 350, а дельта учитывает в общей сложности 700-150 = 550, то ограниченная дельта позволит веслу переместиться в 350-550 = -200, весло переместится 200 пикселей за левым краем.

Так что вам нужно передать методу перемещения верхние границы и ограничить результирующую позицию 0 <= px <= UPPER ... что-то вроде: </p>

    ...
    if(dx!=0) { 
        gobj.moveX(dx,MAX_X); 
        lastX=px;
        }
    ...

GObject:

public void moveX(int dlt, int max) {
    positionX=Util.limitInt((positionX+dlt),0,max);
    }

Util:

/**
 * Limit the range of a number to the specified values.
 */
static public int limitInt(int val, int low, int hgh) {
    return ((val<low) ? low : ((val<hgh) ? val : hgh));
    }

И я бы повторил весь код для Y и управлял бы этой осью отдельно. В противном случае вам нужно будет расширить ваш метод перемещения до:

public void move(int dltX, int maxX, int dltY, int maxY) {
    positionX=Util.limitInt((positionX+dltX),0,maxX);
    positionY=Util.limitInt((positionX+dltY),0,maxY);
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...