1 package org
.eclipse
.tracecompass
.internal
.provisional
.tmf
.ui
.views
.timegraph2
.swtjfx
.examples
;
3 import java
.util
.Arrays
;
4 import java
.util
.HashSet
;
5 import java
.util
.Random
;
8 import org
.eclipse
.jdt
.annotation
.Nullable
;
10 import javafx
.application
.Application
;
11 import javafx
.event
.EventHandler
;
12 import javafx
.scene
.Node
;
13 import javafx
.scene
.Scene
;
14 import javafx
.scene
.control
.Label
;
15 import javafx
.scene
.image
.Image
;
16 import javafx
.scene
.image
.ImageView
;
17 import javafx
.scene
.input
.MouseEvent
;
18 import javafx
.scene
.layout
.Pane
;
19 import javafx
.scene
.layout
.Region
;
20 import javafx
.scene
.paint
.Color
;
21 import javafx
.scene
.shape
.Rectangle
;
22 import javafx
.scene
.shape
.StrokeLineCap
;
23 import javafx
.stage
.Stage
;
25 public class ExampleMouseDrag2
extends Application
{
27 // public static Image image = new Image("http://upload.wikimedia.org/wikipedia/commons/thumb/4/41/Siberischer_tiger_de_edit02.jpg/320px-Siberischer_tiger_de_edit02.jpg");
28 public Image image
= new Image("file:///home/alexandre/Desktop/tiger.jpg");
29 // public Image image = new Image( getClass().getResource( "/home/alexandre/Desktop/tiger.jpg").toExternalForm());
31 SelectionModel selectionModel
= new SelectionModel();
33 DragMouseGestures dragMouseGestures
= new DragMouseGestures();
35 static Random rnd
= new Random();
38 public void start(@Nullable Stage primaryStage
) {
39 if (primaryStage
== null) {
43 Pane pane
= new Pane();
44 pane
.setStyle("-fx-background-color:white");
46 new RubberBandSelection( pane
);
52 for( int row
=0; row
< 4; row
++) {
53 for( int col
=0; col
< 4; col
++) {
55 Selectable selectable
= new Selectable( width
, height
);
56 selectable
.relocate( padding
* (col
+1) + width
* col
, padding
* (row
+ 1) + height
* row
);
58 pane
.getChildren().add(selectable
);
60 dragMouseGestures
.makeDraggable(selectable
);
65 Label infoLabel
= new Label( "Drag on scene for Rubberband Selection. Shift+Click to add to selection, CTRL+Click to toggle selection. Drag selected nodes for multi-dragging.");
66 pane
.getChildren().add( infoLabel
);
68 Scene scene
= new Scene( pane
, 1600, 900);
69 scene
.getStylesheets().add( getClass().getResource("application.css").toExternalForm());
71 primaryStage
.setScene( scene
);
78 private class Selectable
extends Region
{
82 public Selectable( double width
, double height
) {
84 view
= new ImageView( image
);
85 view
.setFitWidth(width
);
86 view
.setFitHeight(height
);
88 getChildren().add( view
);
90 this.setPrefSize(width
, height
);
95 private class SelectionModel
{
97 Set
<Node
> selection
= new HashSet
<>();
99 public void add( Node node
) {
101 if( !node
.getStyleClass().contains("highlight")) {
102 node
.getStyleClass().add( "highlight");
105 selection
.add( node
);
108 public void remove( Node node
) {
109 node
.getStyleClass().remove( "highlight");
110 selection
.remove( node
);
113 public void clear() {
115 while( !selection
.isEmpty()) {
116 remove( selection
.iterator().next());
121 public boolean contains( Node node
) {
122 return selection
.contains(node
);
125 // public int size() {
126 // return selection.size();
130 System
.out
.println( "Items in model: " + Arrays
.asList( selection
.toArray()));
135 private class DragMouseGestures
{
137 final DragContext dragContext
= new DragContext();
139 private boolean enabled
= false;
141 public void makeDraggable(final Node node
) {
143 node
.setOnMousePressed(onMousePressedEventHandler
);
144 node
.setOnMouseDragged(onMouseDraggedEventHandler
);
145 node
.setOnMouseReleased(onMouseReleasedEventHandler
);
149 EventHandler
<MouseEvent
> onMousePressedEventHandler
= new EventHandler
<MouseEvent
>() {
152 public void handle(MouseEvent event
) {
154 // don't do anything if the user is in the process of adding to the selection model
155 if( event
.isControlDown() || event
.isShiftDown()) {
159 Node node
= (Node
) event
.getSource();
161 dragContext
.x
= node
.getTranslateX() - event
.getSceneX();
162 dragContext
.y
= node
.getTranslateY() - event
.getSceneY();
164 // clear the model if the current node isn't in the selection => new selection
165 if( !selectionModel
.contains(node
)) {
166 selectionModel
.clear();
167 selectionModel
.add( node
);
170 // flag that the mouse released handler should consume the event, so it won't bubble up to the pane which has a rubberband selection mouse released handler
173 // prevent rubberband selection handler
178 EventHandler
<MouseEvent
> onMouseDraggedEventHandler
= new EventHandler
<MouseEvent
>() {
181 public void handle(MouseEvent event
) {
188 for( Node node
: selectionModel
.selection
) {
189 node
.setTranslateX( dragContext
.x
+ event
.getSceneX());
190 node
.setTranslateY( dragContext
.y
+ event
.getSceneY());
196 EventHandler
<MouseEvent
> onMouseReleasedEventHandler
= new EventHandler
<MouseEvent
>() {
199 public void handle(MouseEvent event
) {
201 // prevent rubberband selection handler
204 // set node's layout position to current position,remove translate coordinates
205 for( Node node
: selectionModel
.selection
) {
217 * Set node's layout position to current position, remove translate coordinates.
220 private void fixPosition( Node node
) {
222 double x
= node
.getTranslateX();
223 double y
= node
.getTranslateY();
225 node
.relocate(node
.getLayoutX() + x
, node
.getLayoutY() + y
);
227 node
.setTranslateX(0);
228 node
.setTranslateY(0);
241 private class RubberBandSelection
{
243 final DragContext dragContext
= new DragContext();
244 final Rectangle rect
;
247 boolean enabled
= false;
249 public RubberBandSelection( Pane group
) {
253 rect
= new Rectangle( 0,0,0,0);
254 rect
.setStroke(Color
.BLUE
);
255 rect
.setStrokeWidth(1);
256 rect
.setStrokeLineCap(StrokeLineCap
.ROUND
);
257 rect
.setFill(Color
.LIGHTBLUE
.deriveColor(0, 1.2, 1, 0.6));
259 group
.addEventHandler(MouseEvent
.MOUSE_PRESSED
, onMousePressedEventHandler
);
260 group
.addEventHandler(MouseEvent
.MOUSE_DRAGGED
, onMouseDraggedEventHandler
);
261 group
.addEventHandler(MouseEvent
.MOUSE_RELEASED
, onMouseReleasedEventHandler
);
265 EventHandler
<MouseEvent
> onMousePressedEventHandler
= new EventHandler
<MouseEvent
>() {
268 public void handle(MouseEvent event
) {
270 // simple flag to prevent multiple handling of this event or we'd get an exception because rect is already on the scene
271 // eg if you drag with left mouse button and while doing that click the right mouse button
276 dragContext
.mouseAnchorX
= event
.getSceneX();
277 dragContext
.mouseAnchorY
= event
.getSceneY();
279 rect
.setX(dragContext
.mouseAnchorX
);
280 rect
.setY(dragContext
.mouseAnchorY
);
284 group
.getChildren().add( rect
);
292 EventHandler
<MouseEvent
> onMouseReleasedEventHandler
= new EventHandler
<MouseEvent
>() {
295 public void handle(MouseEvent event
) {
297 if( !event
.isShiftDown() && !event
.isControlDown()) {
298 selectionModel
.clear();
301 for( Node node
: group
.getChildren()) {
303 if( node
instanceof Selectable
) {
304 if( node
.getBoundsInParent().intersects( rect
.getBoundsInParent())) {
306 if( event
.isShiftDown()) {
308 selectionModel
.add( node
);
310 } else if( event
.isControlDown()) {
312 if( selectionModel
.contains( node
)) {
313 selectionModel
.remove( node
);
315 selectionModel
.add( node
);
318 selectionModel
.add( node
);
326 selectionModel
.log();
333 group
.getChildren().remove( rect
);
341 EventHandler
<MouseEvent
> onMouseDraggedEventHandler
= new EventHandler
<MouseEvent
>() {
344 public void handle(MouseEvent event
) {
346 double offsetX
= event
.getSceneX() - dragContext
.mouseAnchorX
;
347 double offsetY
= event
.getSceneY() - dragContext
.mouseAnchorY
;
350 rect
.setWidth( offsetX
);
352 rect
.setX(event
.getSceneX());
353 rect
.setWidth(dragContext
.mouseAnchorX
- rect
.getX());
357 rect
.setHeight( offsetY
);
359 rect
.setY(event
.getSceneY());
360 rect
.setHeight(dragContext
.mouseAnchorY
- rect
.getY());
368 private final class DragContext
{
370 public double mouseAnchorX
;
371 public double mouseAnchorY
;
378 public static void main(String
[] args
) {