19 package org.sleuthkit.autopsy.timeline.ui;
21 import javafx.event.EventHandler;
22 import javafx.geometry.Point2D;
23 import javafx.scene.Cursor;
24 import javafx.scene.chart.Axis;
25 import javafx.scene.chart.Chart;
26 import javafx.scene.control.Tooltip;
27 import javafx.scene.input.MouseButton;
28 import javafx.scene.input.MouseEvent;
29 import javafx.scene.paint.Color;
30 import javafx.scene.shape.Rectangle;
31 import org.joda.time.DateTime;
32 import org.joda.time.Interval;
33 import org.openide.util.NbBundle;
82 if (t.getButton() == MouseButton.SECONDARY) {
84 if (t.getEventType() == MouseEvent.MOUSE_PRESSED) {
87 chart.setCursor(Cursor.E_RESIZE);
88 }
else if (t.getEventType() == MouseEvent.MOUSE_DRAGGED) {
89 if (chart.getIntervalSelector() == null) {
91 chart.setIntervalSelector(chart.newIntervalSelector(t.getX(),
dateAxis));
92 chart.getIntervalSelector().heightProperty().bind(chart.heightProperty().subtract(dateAxis.heightProperty().subtract(dateAxis.tickLengthProperty())));
93 chart.getIntervalSelector().addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent event) -> {
94 if (event.getButton() == MouseButton.SECONDARY) {
95 chart.clearIntervalSelector();
103 chart.getIntervalSelector().setX(startX);
104 chart.getIntervalSelector().setWidth(t.getX() -
startX);
106 chart.getIntervalSelector().setX(t.getX());
107 chart.getIntervalSelector().setWidth(startX - t.getX());
110 }
else if (t.getEventType() == MouseEvent.MOUSE_RELEASED) {
111 chart.setCursor(Cursor.DEFAULT);
128 private static final double STROKE_WIDTH = 3;
130 private static final double HALF_STROKE = STROKE_WIDTH / 2;
156 super(x, 0, x, height);
158 setStroke(Color.BLUE);
159 setStrokeWidth(STROKE_WIDTH);
160 setFill(Color.BLUE.deriveColor(0, 1, 1, 0.5));
162 widthProperty().addListener(o -> {
165 xProperty().addListener(o -> {
170 setOnMouseMoved((MouseEvent event) -> {
171 Point2D localMouse = sceneToLocal(
new Point2D(event.getSceneX(),
event.getSceneY()));
172 final double diffX = getX() - localMouse.getX();
173 if (Math.abs(diffX) <= HALF_STROKE || Math.abs(diffX + getWidth()) <= HALF_STROKE) {
174 setCursor(Cursor.E_RESIZE);
176 setCursor(Cursor.HAND);
179 setOnMousePressed((MouseEvent event) -> {
180 Point2D localMouse = sceneToLocal(
new Point2D(event.getSceneX(),
event.getSceneY()));
181 final double diffX = getX() - localMouse.getX();
182 startX =
event.getX();
183 startWidth = getWidth();
185 if (Math.abs(diffX) <= HALF_STROKE) {
187 }
else if (Math.abs(diffX + getWidth()) <= HALF_STROKE) {
193 setOnMouseDragged((MouseEvent event) -> {
194 double dX =
event.getX() - startX;
195 switch (dragPosition) {
197 setX(startLeft + dX);
200 setX(startLeft + dX);
201 setWidth(startWidth - dX);
204 setWidth(startWidth + dX);
209 addEventHandler(MouseEvent.MOUSE_CLICKED,
new EventHandler<MouseEvent>() {
211 public void handle(MouseEvent event) {
212 if (event.getClickCount() >= 2) {
214 DateTime start = parseDateTime(getSpanStart());
215 DateTime end = parseDateTime(getSpanEnd());
217 Interval i = adjustInterval(start.isBefore(end) ? new Interval(start, end) : new Interval(end, start));
219 controller.pushTimeRange(i);
232 protected abstract Interval adjustInterval(Interval i);
240 protected abstract String formatSpan(
final X date);
247 protected abstract DateTime parseDateTime(X date);
250 final X start = getSpanStart();
251 final X end = getSpanEnd();
252 Tooltip.uninstall(
this, tooltip);
253 tooltip =
new Tooltip(
254 NbBundle.getMessage(
this.getClass(),
"Timeline.ui.TimeLineChart.tooltip.text", formatSpan(start),
256 Tooltip.install(
this, tooltip);
262 return dateAxis.getValueForDisplay(dateAxis.parentToLocal(getBoundsInParent().getMaxX(), 0).getX());
268 return dateAxis.getValueForDisplay(dateAxis.parentToLocal(getBoundsInParent().getMinX(), 0).getX());
void clearIntervalSelector()
void handle(MouseEvent t)
ChartDragHandler(Y chart, Axis< X > dateAxis)
DragPosition dragPosition
void setIntervalSelector(IntervalSelector<?extends X > newIntervalSelector)
IntervalSelector(double x, double height, Axis< X > axis, TimeLineController controller)
IntervalSelector< X > newIntervalSelector(double x, Axis< X > axis)
IntervalSelector<?extends X > getIntervalSelector()