Skip to content

Commit a95b332

Browse files
committed
add draw status changed listener to load camera controller. Reorganise UI following Tyler suggestions.
1 parent 7e59b26 commit a95b332

File tree

2 files changed

+130
-107
lines changed

2 files changed

+130
-107
lines changed

src/main/java/com/esri/samples/scene/orbit_the_camera_around_an_object/OrbitTheCameraAroundAnObjectController.java

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818

1919
import java.io.File;
2020

21+
import com.esri.arcgisruntime.mapping.view.DrawStatus;
22+
import com.esri.arcgisruntime.mapping.view.DrawStatusChangedEvent;
23+
import com.esri.arcgisruntime.mapping.view.DrawStatusChangedListener;
2124
import javafx.fxml.FXML;
2225
import javafx.scene.control.CheckBox;
2326
import javafx.scene.control.Slider;
@@ -91,35 +94,50 @@ public void initialize() {
9194
// control the plane's pitch with a slider
9295
planePitchSlider.valueProperty().addListener(o -> plane.getAttributes().put("PITCH", planePitchSlider.getValue()));
9396

94-
// create an orbit geoelement camera controller with the plane as the target
95-
orbitCameraController = new OrbitGeoElementCameraController(plane, 50.0);
97+
// listener for the view to stop loading and to add the camera controller
98+
DrawStatusChangedListener listener = new DrawStatusChangedListener() {
9699

97-
// restrict the camera's heading to stay behind the plane
98-
orbitCameraController.setMinCameraHeadingOffset(-45);
99-
orbitCameraController.setMaxCameraHeadingOffset(45);
100+
@Override
101+
public void drawStatusChanged(DrawStatusChangedEvent drawStatusChangedEvent) {
102+
if (drawStatusChangedEvent.getDrawStatus() == DrawStatus.COMPLETED) {
100103

101-
// restrict the camera's pitch so it doesn't go completely vertical or collide with the ground
102-
orbitCameraController.setMinCameraPitchOffset(10);
103-
orbitCameraController.setMaxCameraPitchOffset(100);
104+
// create an orbit geoelement camera controller with the plane as the target
105+
orbitCameraController = new OrbitGeoElementCameraController(plane, 50.0);
104106

105-
// restrict the camera to stay between 10 and 1000 meters from the plane
106-
orbitCameraController.setMinCameraDistance(10);
107-
orbitCameraController.setMaxCameraDistance(100);
107+
// restrict the camera's heading to stay behind the plane
108+
orbitCameraController.setMinCameraHeadingOffset(-45);
109+
orbitCameraController.setMaxCameraHeadingOffset(45);
108110

109-
// position the plane a third from the bottom of the screen
110-
orbitCameraController.setTargetVerticalScreenFactor(0.33f);
111+
// restrict the camera's pitch so it doesn't go completely vertical or collide with the ground
112+
orbitCameraController.setMinCameraPitchOffset(10);
113+
orbitCameraController.setMaxCameraPitchOffset(100);
111114

112-
// don't pitch the camera when the plane pitches
113-
orbitCameraController.setAutoPitchEnabled(false);
115+
// restrict the camera to stay between 10 and 1000 meters from the plane
116+
orbitCameraController.setMinCameraDistance(10);
117+
orbitCameraController.setMaxCameraDistance(100);
114118

115-
// set the orbit camera controller to the scene view
116-
sceneView.setCameraController(orbitCameraController);
119+
// position the plane a third from the bottom of the screen
120+
orbitCameraController.setTargetVerticalScreenFactor(0.33f);
117121

118-
// set the camera's heading using a slider
119-
cameraHeadingSlider.valueProperty().addListener(o -> orbitCameraController.setCameraHeadingOffset(cameraHeadingSlider.getValue()));
122+
// don't pitch the camera when the plane pitches
123+
orbitCameraController.setAutoPitchEnabled(false);
120124

121-
// update camera heading slider position whilst interacting with the camera heading
122-
sceneView.addViewpointChangedListener( event -> cameraHeadingSlider.setValue(orbitCameraController.getCameraHeadingOffset()));
125+
// set the orbit camera controller to the scene view
126+
sceneView.setCameraController(orbitCameraController);
127+
128+
// set the camera's heading using a slider
129+
cameraHeadingSlider.valueProperty().addListener(o -> orbitCameraController.setCameraHeadingOffset(cameraHeadingSlider.getValue()));
130+
131+
// update camera heading slider position whilst interacting with the camera heading
132+
sceneView.addViewpointChangedListener( event -> cameraHeadingSlider.setValue(orbitCameraController.getCameraHeadingOffset()));
133+
134+
// stop listening for the view to load
135+
sceneView.removeDrawStatusChangedListener(this);
136+
}
137+
}
138+
};
139+
140+
sceneView.addDrawStatusChangedListener(listener);
123141

124142
} catch (Exception e) {
125143
// on any exception, print the stack trace

src/main/resources/fxml/orbit_the_camera_around_an_object.fxml

Lines changed: 91 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -16,106 +16,111 @@
1616
~ the License.
1717
-->
1818

19+
1920
<?import javafx.geometry.Insets?>
2021
<?import javafx.scene.control.Button?>
22+
<?import javafx.scene.control.CheckBox?>
2123
<?import javafx.scene.control.Label?>
22-
<?import javafx.scene.control.Separator?>
2324
<?import javafx.scene.control.Slider?>
2425
<?import javafx.scene.layout.Background?>
2526
<?import javafx.scene.layout.BackgroundFill?>
27+
<?import javafx.scene.layout.BorderPane?>
2628
<?import javafx.scene.layout.StackPane?>
2729
<?import javafx.scene.layout.VBox?>
2830
<?import javafx.scene.paint.Color?>
2931
<?import com.esri.arcgisruntime.mapping.view.SceneView?>
30-
<?import javafx.scene.control.CheckBox?>
3132
<?import javafx.scene.layout.HBox?>
32-
<StackPane fx:controller="com.esri.samples.scene.orbit_the_camera_around_an_object.OrbitTheCameraAroundAnObjectController"
33-
xmlns:fx="http://javafx.com/fxml"
34-
stylesheets="/css/style.css">
33+
<StackPane
34+
fx:id="stackpane"
35+
fx:controller="com.esri.samples.scene.orbit_the_camera_around_an_object.OrbitTheCameraAroundAnObjectController"
36+
xmlns:fx="http://javafx.com/fxml"
37+
stylesheets="/css/style.css">
3538
<SceneView fx:id="sceneView"/>
3639

37-
<!--View buttons-->
38-
<VBox StackPane.alignment="BOTTOM_RIGHT" maxWidth="200" maxHeight="50" styleClass="panel-region" spacing="11" alignment="TOP_CENTER">
39-
<StackPane.margin>
40-
<Insets bottom="20" right="10"/>
41-
</StackPane.margin>
42-
<padding>
43-
<Insets topRightBottomLeft="10"/>
44-
</padding>
45-
<Button text="Cockpit view" maxWidth="Infinity" onAction="#handleCockpitViewButtonClicked"/>
46-
<Button text="Center view" maxWidth="Infinity" onAction="#handleFollowViewButtonClicked"/>
47-
48-
<background>
49-
<Background>
50-
<fills>
51-
<BackgroundFill>
52-
<fill>
53-
<Color opacity="0.3"/>
54-
</fill>
55-
</BackgroundFill>
56-
</fills>
57-
</Background>
58-
</background>
59-
</VBox>
40+
<BorderPane pickOnBounds="false">
41+
<top>
42+
<!--View buttons-->
43+
<VBox StackPane.alignment="TOP_LEFT" maxWidth="200" maxHeight="50" styleClass="panel-region" spacing="11"
44+
alignment="TOP_CENTER">
45+
<StackPane.margin>
46+
<Insets bottom="20" right="10"/>
47+
</StackPane.margin>
48+
<padding>
49+
<Insets topRightBottomLeft="10"/>
50+
</padding>
51+
<Button text="Cockpit view" maxWidth="Infinity" onAction="#handleCockpitViewButtonClicked"/>
52+
<Button text="Center view" maxWidth="Infinity" onAction="#handleFollowViewButtonClicked"/>
6053

61-
<!--Camera heading-->
62-
<VBox StackPane.alignment="BOTTOM_LEFT" maxWidth="500" maxHeight="50" styleClass="panel-region" spacing="6">
63-
<StackPane.margin>
64-
<Insets bottom="20" left="10"/>
65-
</StackPane.margin>
66-
<padding>
67-
<Insets top="10" left="30" right="30" bottom="10"/>
68-
</padding>
69-
<HBox alignment="TOP_LEFT" maxWidth="Infinity">
70-
<Label text="Camera Heading" maxWidth="Infinity" HBox.hgrow="ALWAYS">
71-
<!--<padding>-->
72-
<!--<Insets left="10" right="130"/>-->
73-
<!--</padding>-->
74-
</Label>
75-
<CheckBox fx:id="allowDistanceInteractionCheckBox" text="Allow camera distance interaction" selected="true"
76-
onAction="#handleDistanceInteractionCheckBoxToggle" HBox.hgrow="ALWAYS"/>
77-
</HBox>
78-
79-
<Slider fx:id="cameraHeadingSlider" min="-180" max="180" majorTickUnit="90" showTickMarks="true"
80-
showTickLabels="true" maxWidth="Infinity" VBox.vgrow="ALWAYS"/>
81-
<background>
82-
<Background>
83-
<fills>
84-
<BackgroundFill>
85-
<fill>
86-
<Color opacity="0.3"/>
87-
</fill>
88-
</BackgroundFill>
89-
</fills>
90-
</Background>
91-
</background>
92-
</VBox>
93-
94-
<!--Plane pitch-->
95-
<VBox StackPane.alignment="CENTER_RIGHT" alignment="CENTER" maxWidth="100" maxHeight="300" styleClass="panel-region"
96-
spacing="6">
97-
<StackPane.margin>
98-
<Insets right="10" top="110"/>
99-
</StackPane.margin>
100-
<padding>
101-
<Insets topRightBottomLeft="10"/>
102-
</padding>
103-
<Label text="Plane Pitch"/>
104-
<Slider fx:id="planePitchSlider" orientation="VERTICAL" min="-90" max="90" majorTickUnit="45" showTickMarks="true"
105-
showTickLabels="true" maxHeight="Infinity" VBox.vgrow="ALWAYS"/>
106-
<background>
107-
<Background>
108-
<fills>
109-
<BackgroundFill>
110-
<fill>
111-
<Color opacity="0.3"/>
112-
</fill>
113-
</BackgroundFill>
114-
</fills>
115-
</Background>
116-
</background>
117-
</VBox>
54+
<background>
55+
<Background>
56+
<fills>
57+
<BackgroundFill>
58+
<fill>
59+
<Color opacity="0.3"/>
60+
</fill>
61+
</BackgroundFill>
62+
</fills>
63+
</Background>
64+
</background>
65+
</VBox>
66+
</top>
67+
<right>
68+
<!--Plane pitch-->
69+
<VBox BorderPane.alignment="CENTER_RIGHT" alignment="CENTER" maxWidth="100" maxHeight="300"
70+
styleClass="panel-region" spacing="6">
71+
<StackPane.margin>
72+
<Insets right="10"/>
73+
</StackPane.margin>
74+
<padding>
75+
<Insets topRightBottomLeft="10"/>
76+
</padding>
77+
<Label text="Plane Pitch"/>
78+
<Slider fx:id="planePitchSlider" orientation="VERTICAL" min="-90" max="90" majorTickUnit="45" showTickMarks="true"
79+
showTickLabels="true" maxHeight="Infinity" VBox.vgrow="ALWAYS"/>
80+
<background>
81+
<Background>
82+
<fills>
83+
<BackgroundFill>
84+
<fill>
85+
<Color opacity="0.3"/>
86+
</fill>
87+
</BackgroundFill>
88+
</fills>
89+
</Background>
90+
</background>
91+
</VBox>
92+
</right>
93+
<bottom>
94+
<!--Camera heading-->
95+
<VBox BorderPane.alignment="BOTTOM_CENTER" minWidth="100" maxWidth="500" maxHeight="50"
96+
styleClass="panel-region" spacing="6">
97+
<BorderPane.margin>
98+
<Insets topRightBottomLeft="20"/>
99+
</BorderPane.margin>
100+
<padding>
101+
<Insets topRightBottomLeft="10"/>
102+
</padding>
103+
<HBox maxWidth="Infinity">
104+
<Label text="Camera Heading" HBox.hgrow="ALWAYS" maxWidth="Infinity"/>
105+
<CheckBox fx:id="allowDistanceInteractionCheckBox" text="Allow camera distance interaction"
106+
selected="true" onAction="#handleDistanceInteractionCheckBoxToggle"/>
107+
</HBox>
108+
<Slider fx:id="cameraHeadingSlider" min="-180" max="180" majorTickUnit="90" showTickMarks="true"
109+
showTickLabels="true" HBox.hgrow="ALWAYS"/>
110+
<background>
111+
<Background>
112+
<fills>
113+
<BackgroundFill>
114+
<fill>
115+
<Color opacity="0.3"/>
116+
</fill>
117+
</BackgroundFill>
118+
</fills>
119+
</Background>
120+
</background>
121+
</VBox>
122+
</bottom>
123+
</BorderPane>
118124
</StackPane>
119125

120126

121-

0 commit comments

Comments
 (0)