В настоящее время мы работаем над исправлениями для проекта, который должен быть завершен на следующей неделе, поэтому у нас как бы заканчивается время (не волнуйтесь, все, что я хочу сказать, это то, что у нас нет времени отбросить весь наш код и начать заново заново ...).
У нас есть JPanel
(= "страница") с кучей других JPanels
(которые действуют как узлы графа) на нем. Пользователь может соединить узлы, щелкнув по первому, а затем по второму узлу для соединения, или перетащив линию из одного в другой.
Но последний не работает, как мы ожидали:
Если мы перетащим линию соединения из узла, где она была запущена (например, на страницу или любой другой узел), событие mouseDragged
, которое мы используем для создания линии, не заканчивается на mouseRelease
. Это прекрасно работает, если я отпущу мышь над узлом, где я начал перетаскивать, но я не могу создать какие-либо связи с этим.
Чтобы установить связь со страницей, мы отправляем события до тех пор, пока они не достигнут страницы, на которой они будут обрабатываться.
Забавная вещь: все работает, за исключением того, что у нас есть бесконечная цепочка «перетаскиваемых мышью» выходов, если мы вставим System.out.println("mouse dragged");
в код mouseDragged()
.
Само соединение работает с.
Итак, мой вопрос: как мне завершить событие mouseDragged
, если mouseReleased
происходит за пределами компонента, где изначально был mouseDragged
?
Есть ли способ отменить событие mouseDragged
?
Возможно / необходимо "подделать" прерывающее событие mouseRelease
?
Надеюсь, что есть решение, которое не заставит готовить больше кофе ....
Привет,
Flo
EDIT:
хорошо, есть код для вас:
Интерфейс, реализованный узлами и страницей, упрощает работу:
import java.awt.event.MouseEvent;
/**
* Interface which can be used together with MouseEventListenerAdapter to
* easily receive mouse events.
*
* @author flo
*/
public interface MouseEventsInterface {
/**
* Called when a mouse clicked event is received.
*
* @param e Triggered mouse event.
*/
void onMouseClicked(MouseEvent e);
/**
* Called when a mouse dragged event is received.
*
* @param e Triggered mouse event.
*/
void onMouseDragged(MouseEvent e);
[and so on...]
/**
* Called when a mouse released event is received.
*
* @param e Triggered mouse event.
*/
void onMouseReleased(MouseEvent e);
}
Адаптер к событиям
/**
* Class which forwards mouse events to a MouseEventsInterface which have
* originally been targeted to a MouseInputAdapter.
*
* @author flo
*
* @param <M> The interface to which events are sent.
*/
public class MouseEventListenerAdapter<M extends MouseEventsInterface> extends MouseInputAdapter {
/**
* Interface which receives the events which are forwarded by this class.
*/
private M mei;
/**
* Creates an adapter which forwards all events to the MouseEventsInterface.
*
* @param mei The receiver of the forwarded events.
*/
public MouseEventListenerAdapter(final M mei) {
this.mei = mei;
}
@Override
public final void mousePressed(final MouseEvent e) {
this.mei.onMousePressed(e);
}
@Override
public final void mouseClicked(final MouseEvent e) {
this.mei.onMouseClicked(e);
}
@Override
public final void mouseDragged(final MouseEvent e) {
this.mei.onMouseDragged(e);
}
@Override
public final void mouseMoved(final MouseEvent e) {
this.mei.onMouseMoved(e);
}
@Override
public final void mouseReleased(final MouseEvent e) {
this.mei.onMouseReleased(e);
}
/**
* Returns the receiver of the forwarded {@link MouseEvent MouseEvents}.
* @return the receiver of the forwarded {@link MouseEvent MouseEvents}.
*/
protected final M getEventReceiver() {
return this.mei;
}
}
как мы отправляем события, первая часть используется, если событие происходит из другой панели внутри узла.
NodeConnectorMouseEvent - это обычное MouseEvent с возможностью хранения всех компонентов, из которых оно было отправлено ...
/**
* Dispatch mouse event.
*
* @param e the e
*/
private void dispatchMouseEvent(final MouseEvent e) {
if (e instanceof NodeConnectorMouseEvent) {
((NodeConnectorMouseEvent) e).addDispatchingComponent(this);
} else {
// f.e. moved over IOPort, PortPanel
e.setSource(this);
}
this.getParent().dispatchEvent(e);
}
часть кода страницы:
@Override
public final void onMouseDragged(final MouseEvent e) {
System.out.println("Mouse: dragged");
if (isDragGestureActive) {
if (helperConnection != null && e instanceof NodeConnectorMouseEvent) {
NodeConnectorMouseEvent evt = (NodeConnectorMouseEvent) e;
if (containsIoPort(evt) != null && weAreDragging) {
Point absPosition = calcAbsolutePosition(evt);
// Discard drag events that would jump farther than 15 pixels,
//but only if we actually weren't dragging
if (weAreDragging
&& (Math.abs(absPosition.x - lastDragPosition.x) < 15
&& Math.abs(absPosition.y - lastDragPosition.y) < 15)) {
updateHelperConnection(absPosition);
}
lastDragPosition = absPosition;
}
} else if (e.getSource() instanceof EditorNode) {
moveSelectedNodes((EditorNode) e.getSource(), e.getX() - grabPosition.x, e.getY() - grabPosition.y);
} else {
return;
}
} else {
return;
}
}
@Override
public final void onMouseReleased(final MouseEvent e) {
System.out.println("Mouse: released");
if (e instanceof NodeConnectorMouseEvent) {
NodeConnectorMouseEvent evt = (NodeConnectorMouseEvent) e;
IOPort port = containsIoPort(evt);
if (port != null) {
weAreDragging = false;
lastDragPosition = new Point(0, 0);
onPortSelected(port);
}
} else if (e.getSource() instanceof EditorNode) {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
} else {
finishHelperConnection(null);
}
isDragGestureActive = false;
}
Это намного больше, но я думаю, это была интересная часть.
Спасибо за вашу помощь!