1 package org
.lttng
.scope
.tmf2
.views
.ui
.jfx
.examples
;
3 import java
.net
.MalformedURLException
;
5 import org
.eclipse
.jdt
.annotation
.NonNullByDefault
;
7 import javafx
.application
.Application
;
8 import javafx
.geometry
.Bounds
;
9 import javafx
.geometry
.Point2D
;
10 import javafx
.geometry
.Pos
;
11 import javafx
.scene
.Group
;
12 import javafx
.scene
.Node
;
13 import javafx
.scene
.Scene
;
14 import javafx
.scene
.canvas
.Canvas
;
15 import javafx
.scene
.canvas
.GraphicsContext
;
16 import javafx
.scene
.control
.Label
;
17 import javafx
.scene
.control
.ScrollPane
;
18 import javafx
.scene
.control
.SplitPane
;
19 import javafx
.scene
.layout
.Pane
;
20 import javafx
.scene
.layout
.Region
;
21 import javafx
.scene
.layout
.StackPane
;
22 import javafx
.scene
.paint
.Color
;
23 import javafx
.scene
.shape
.Circle
;
24 import javafx
.stage
.Stage
;
27 public class ZoomExample
extends Application
{
29 public static Region
createContent() {
33 Canvas canvas
= new Canvas(width
, height
);
34 GraphicsContext gc
= canvas
.getGraphicsContext2D();
36 gc
.setFill(Color
.LIGHTGREY
);
37 gc
.fillRect(0, 0, width
, height
);
39 gc
.setStroke(Color
.BLUE
);
42 for (int i
= 50; i
< width
; i
+= 50) {
47 for (int i
= 50; i
< height
; i
+= 50) {
53 Pane content
= new Pane(
54 new Circle(50, 50, 20),
55 new Circle(120, 90, 20, Color
.RED
),
56 new Circle(200, 70, 20, Color
.GREEN
)
59 StackPane result
= new StackPane(canvas
, content
);
60 result
.setAlignment(Pos
.TOP_LEFT
);
71 DragData dragData
= new DragData();
73 content
.setOnMousePressed(evt
-> {
74 if (evt
.getTarget() != content
) {
75 // initiate drag gesture, if a child of content receives the
76 // event to prevent ScrollPane from panning.
78 evt
.setDragDetect(true);
82 content
.setOnDragDetected(evt
-> {
83 Node n
= (Node
) evt
.getTarget();
85 // set start paremeters
86 while (n
.getParent() != content
) {
89 dragData
.startX
= evt
.getX();
90 dragData
.startY
= evt
.getY();
91 dragData
.startLayoutX
= n
.getLayoutX();
92 dragData
.startLayoutY
= n
.getLayoutY();
93 dragData
.dragTarget
= n
;
99 // stop dragging when mouse is released
100 content
.setOnMouseReleased(evt
-> dragData
.dragTarget
= null);
102 content
.setOnMouseDragged(evt
-> {
103 if (dragData
.dragTarget
!= null) {
105 dragData
.dragTarget
.setLayoutX(evt
.getX() + dragData
.startLayoutX
- dragData
.startX
);
106 dragData
.dragTarget
.setLayoutY(evt
.getY() + dragData
.startLayoutY
- dragData
.startY
);
107 // Point2D p = new Point2D(evt.getX(), evt.getY());
116 public void start(Stage primaryStage
) throws MalformedURLException
{
117 Region zoomTarget
= createContent();
118 zoomTarget
.setPrefSize(1000, 1000);
119 zoomTarget
.setOnDragDetected(evt
-> {
120 Node target
= (Node
) evt
.getTarget();
121 while (target
!= zoomTarget
&& target
!= null) {
122 target
= target
.getParent();
124 if (target
!= null) {
125 target
.startFullDrag();
129 Group group
= new Group(zoomTarget
);
131 // stackpane for centering the content, in case the ScrollPane viewport
132 // is larget than zoomTarget
133 StackPane content
= new StackPane(group
);
134 group
.layoutBoundsProperty().addListener((observable
, oldBounds
, newBounds
) -> {
135 // keep it at least as large as the content
136 content
.setMinWidth(newBounds
.getWidth());
137 content
.setMinHeight(newBounds
.getHeight());
140 ScrollPane scrollPane
= new ScrollPane(content
);
141 scrollPane
.setPannable(true);
142 scrollPane
.viewportBoundsProperty().addListener((observable
, oldBounds
, newBounds
) -> {
143 // use vieport size, if not too small for zoomTarget
144 content
.setPrefSize(newBounds
.getWidth(), newBounds
.getHeight());
147 content
.setOnScroll(evt
-> {
148 if (evt
.isControlDown()) {
151 final double zoomFactor
= evt
.getDeltaY() > 0 ?
1.2 : 1 / 1.2;
153 Bounds groupBounds
= group
.getLayoutBounds();
154 final Bounds viewportBounds
= scrollPane
.getViewportBounds();
156 // calculate pixel offsets from [0, 1] range
157 double valX
= scrollPane
.getHvalue() * (groupBounds
.getWidth() - viewportBounds
.getWidth());
158 double valY
= scrollPane
.getVvalue() * (groupBounds
.getHeight() - viewportBounds
.getHeight());
160 // convert content coordinates to zoomTarget coordinates
161 Point2D posInZoomTarget
= zoomTarget
.parentToLocal(group
.parentToLocal(new Point2D(evt
.getX(), evt
.getY())));
163 // calculate adjustment of scroll position (pixels)
164 Point2D adjustment
= zoomTarget
.getLocalToParentTransform().deltaTransform(posInZoomTarget
.multiply(zoomFactor
- 1));
167 zoomTarget
.setScaleX(zoomFactor
* zoomTarget
.getScaleX());
168 zoomTarget
.setScaleY(zoomFactor
* zoomTarget
.getScaleY());
170 // refresh ScrollPane scroll positions & content bounds
173 // convert back to [0, 1] range
174 // (too large/small values are automatically corrected by ScrollPane)
175 groupBounds
= group
.getLayoutBounds();
176 scrollPane
.setHvalue((valX
+ adjustment
.getX()) / (groupBounds
.getWidth() - viewportBounds
.getWidth()));
177 scrollPane
.setVvalue((valY
+ adjustment
.getY()) / (groupBounds
.getHeight() - viewportBounds
.getHeight()));
181 StackPane left
= new StackPane(new Label("Left Menu"));
182 SplitPane root
= new SplitPane(left
, scrollPane
);
184 Scene scene
= new Scene(root
, 800, 600);
186 primaryStage
.setScene(scene
);
190 public static void main(String
[] args
) {
This page took 0.036068 seconds and 5 git commands to generate.