ComponentDragEventDelegate.java
package swingtree;
import sprouts.Action;
import sprouts.Tuple;
import swingtree.layout.Position;
import javax.swing.JComponent;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.util.List;
/**
* A {@link JComponent} and {@link MouseEvent} delegate providing useful context information to various {@link sprouts.Action} listeners
* used by {@link UIForAnySwing#onMouseDrag(Action)} like for example the {@link #mouseX()} and
* {@link #mouseY()} of the event as well as more drag specific information like
* {@link #dragEvents()} and {@link #dragPositions()}.
*
* @param <C> The type of {@link JComponent} that this {@link ComponentDragEventDelegate} is delegating to.
*/
public final class ComponentDragEventDelegate<C extends JComponent> extends ComponentMouseEventDelegate<C>
{
private final Tuple<MouseEvent> _dragEventHistory;
ComponentDragEventDelegate(
C component,
MouseEvent event,
List<MouseEvent> dragEventHistory
) {
super(component, event);
_dragEventHistory = Tuple.of(MouseEvent.class, dragEventHistory);
}
/**
* Provides a {@link Tuple} (immutable list) of all {@link MouseEvent}s of a
* continuous mouse drag performed on the component.
* When a drag ends, the tuple is empty.
*
* @return A tuple of all {@link MouseEvent}s of a continuous mouse drag performed on the component.
*/
public Tuple<MouseEvent> dragEvents() {
return _dragEventHistory;
}
/**
* SwingTree keeps track of the most recent mouse drag events of a continuous drag.
* This method returns a {@link Tuple} (immutable list) of all mouse {@link Position}s
* of a continuous mouse drag performed on the component. <br>
* Note that these points are scaled to "developer pixel" instead of the actual "UI scaled component space"
* of the underlying Swing component.<br>
* Use {@link UI#scale(int)} to convert these points back to the actual "UI scaled component space".
* Also note that this method returns an unmodifiable list consisting
* of immutable {@link Position} objects instead of mutable {@link Point} objects,
* to protect the client from side effects.
*
* @return A tuple (immutable list) of all mouse {@link Position}s of a continuous mouse drag performed on the component.
* The points of this list represent the mouse movement track since the start of a continuous drag.
*/
public Tuple<Position> dragPositions() {
return _dragEventHistory.stream()
.map(it->Position.of(UI.unscale(it.getX()), UI.unscale(it.getY())))
.collect(Tuple.collectorOf(Position.class));
}
/**
* Provides the x-axis movement delta of the mouse since the start of a continuous drag <b>without DPI scaling</b>.
* So the value is in "developer pixel" not in <b>UI scaled component space</b>.
* This means that when you need to interface with the underlying Swing API then you may
* want to consider upscaling it again using {@link UI#scale(float)}.
*
* @return The x-axis movement delta of the mouse since the start of a continuous drag.
* This value is in "developer pixel" not in <b>UI scaled component space</b>.
*/
public float deltaXSinceStart() {
if (_dragEventHistory.size() < 2) return 0;
float xInComponentPixel = _dragEventHistory.get(_dragEventHistory.size() - 1).getX() - _dragEventHistory.get(0).getX();
return UI.unscale(xInComponentPixel);
}
/**
* Provides the y-axis movement delta of the mouse since the start of a continuous drag <b>without DPI scaling</b>.
* So the value is in "developer pixel" not in <b>UI scaled component space</b>.
* This means that when you need to interface with the underlying Swing API then you may
* want to consider upscaling it again using {@link UI#scale(float)}.
* @return The y-axis movement delta of the mouse since the start of a continuous drag.
* This value is in "developer pixel" not in <b>UI scaled component space</b>.
*/
public float deltaYSinceStart() {
if (_dragEventHistory.size() < 2) return 0;
float yInComponentPixel = _dragEventHistory.get(_dragEventHistory.size() - 1).getY() - _dragEventHistory.get(0).getY();
return UI.unscale(yInComponentPixel);
}
}