1 /*
2 * Copyright (c) 2008, 2016, Oracle and/or its affiliates.
3 * All rights reserved. Use is subject to license terms.
4 *
5 * This file is available and licensed under the following license:
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the distribution.
16 * - Neither the name of Oracle Corporation nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 package ensemble.samples.graphics3d.xylophone;
33
34 import javafx.animation.Interpolator;
35 import javafx.animation.KeyFrame;
36 import javafx.animation.KeyValue;
37 import javafx.animation.Timeline;
38 import javafx.application.Application;
39 import javafx.scene.Group;
40 import javafx.scene.SceneAntialiasing;
41 import javafx.scene.Parent;
42 import javafx.scene.PerspectiveCamera;
43 import javafx.scene.Scene;
44 import javafx.scene.SubScene;
45 import javafx.scene.input.MouseEvent;
46 import javafx.scene.media.AudioClip;
47 import javafx.scene.paint.Color;
48 import javafx.scene.paint.PhongMaterial;
49 import javafx.scene.shape.Box;
50 import javafx.stage.Stage;
51 import javafx.util.Duration;
52
53 /**
61 * @see javafx.scene.SceneAntialiasing
62 * @see javafx.scene.SubScene
63 * @see javafx.scene.input.MouseEvent
64 * @see javafx.scene.media.AudioClip
65 * @see javafx.scene.paint.PhongMaterial
66 * @see javafx.scene.shape.Box
67 * @see javafx.scene.transform.Rotate
68 * @see javafx.scene.transform.Scale
69 * @conditionalFeatures SCENE3D
70 *
71 * @related /Graphics 3d/3D Box
72 * @related /Graphics 3d/3D Cubes
73 * @related /Graphics 3d/3D Sphere
74 * @related /Graphics 3d/3D Sphere System
75 */
76 public class XylophoneApp extends Application {
77
78 private Timeline animation;
79 private Timeline animation2;
80
81 private static final String[] urls = {
82 "/ensemble/samples/shared-resources/Note1.wav",
83 "/ensemble/samples/shared-resources/Note2.wav",
84 "/ensemble/samples/shared-resources/Note3.wav",
85 "/ensemble/samples/shared-resources/Note4.wav",
86 "/ensemble/samples/shared-resources/Note5.wav",
87 "/ensemble/samples/shared-resources/Note6.wav",
88 "/ensemble/samples/shared-resources/Note7.wav",
89 "/ensemble/samples/shared-resources/Note8.wav"
90 };
91
92 public Parent createContent() {
93 Xform sceneRoot = new Xform();
94 sceneRoot.rx.setAngle(45.0);
95 sceneRoot.ry.setAngle(30.0);
96 sceneRoot.setScale(2 * 1.5);
97
98 Group rectangleGroup = new Group();
99
100 double xStart = -110.0;
101 double xOffset = 30.0;
102 double yPos = 25.0;
103 double barWidth = 22.0;
104 double barDepth = 7.0;
105
106 // Base1
107 Box base1Cube = new Box(barWidth * 11.5, barDepth * 2.0, 10.0);
108 base1Cube.setMaterial(new PhongMaterial(new Color(0.2, 0.12, 0.1, 1.0)));
109 base1Cube.setTranslateX(xStart + 128);
110 base1Cube.setTranslateZ(yPos + 20.0);
111 base1Cube.setTranslateY(11.0);
112
113 // Base2
114 Box base2Cube = new Box(barWidth * 11.5, barDepth * 2.0, 10.0);
115 base2Cube.setMaterial(new PhongMaterial(new Color(0.2, 0.12, 0.1, 1.0)));
116 base2Cube.setTranslateX(xStart + 128);
117 base2Cube.setTranslateZ(yPos - 20.0);
118 base2Cube.setTranslateY(11.0);
119
120 Box[] barCubes = new Box[8];
121 Color[] colors = {
122 Color.PURPLE, Color.BLUEVIOLET, Color.BLUE, Color.GREEN,
123 Color.GREENYELLOW, Color.YELLOW, Color.ORANGE, Color.RED
124 };
125 for (int i = 0; i < barCubes.length; i++) {
126 String url = getClass().getResource(urls[i]).toString();
127 final AudioClip barNote = new AudioClip(url);
128
129 barCubes[i] = new Box(barWidth, barDepth, 100.0 - (i * 5.0));
130 barCubes[i].setTranslateX(xStart + ((1 + i) * xOffset));
131 barCubes[i].setTranslateZ(yPos);
132 barCubes[i].setMaterial(new PhongMaterial(colors[i]));
133 barCubes[i].setOnMousePressed((MouseEvent me) -> {
134 barNote.play();
135 });
136 }
137
138 rectangleGroup.getChildren().addAll(base1Cube, base2Cube);
139 rectangleGroup.getChildren().addAll(java.util.Arrays.asList(barCubes));
140 sceneRoot.getChildren().add(rectangleGroup);
141
142 animation = new Timeline();
143 animation.getKeyFrames().addAll(new KeyFrame(Duration.ZERO,
144 new KeyValue(sceneRoot.ry.angleProperty(), 390d,
145 Interpolator.TANGENT(Duration.seconds(0.5), 390d,
146 Duration.seconds(0.5), 390d))),
147 new KeyFrame(Duration.seconds(2),
|
1 /*
2 * Copyright (c) 2008, 2017, Oracle and/or its affiliates.
3 * All rights reserved. Use is subject to license terms.
4 *
5 * This file is available and licensed under the following license:
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the distribution.
16 * - Neither the name of Oracle Corporation nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 package ensemble.samples.graphics3d.xylophone;
33
34 import ensemble.samples.media.audioclip.AudioClipApp;
35 import java.io.File;
36 import java.net.HttpURLConnection;
37 import java.net.URI;
38 import java.net.URL;
39 import javafx.animation.Interpolator;
40 import javafx.animation.KeyFrame;
41 import javafx.animation.KeyValue;
42 import javafx.animation.Timeline;
43 import javafx.application.Application;
44 import javafx.scene.Group;
45 import javafx.scene.SceneAntialiasing;
46 import javafx.scene.Parent;
47 import javafx.scene.PerspectiveCamera;
48 import javafx.scene.Scene;
49 import javafx.scene.SubScene;
50 import javafx.scene.input.MouseEvent;
51 import javafx.scene.media.AudioClip;
52 import javafx.scene.paint.Color;
53 import javafx.scene.paint.PhongMaterial;
54 import javafx.scene.shape.Box;
55 import javafx.stage.Stage;
56 import javafx.util.Duration;
57
58 /**
66 * @see javafx.scene.SceneAntialiasing
67 * @see javafx.scene.SubScene
68 * @see javafx.scene.input.MouseEvent
69 * @see javafx.scene.media.AudioClip
70 * @see javafx.scene.paint.PhongMaterial
71 * @see javafx.scene.shape.Box
72 * @see javafx.scene.transform.Rotate
73 * @see javafx.scene.transform.Scale
74 * @conditionalFeatures SCENE3D
75 *
76 * @related /Graphics 3d/3D Box
77 * @related /Graphics 3d/3D Cubes
78 * @related /Graphics 3d/3D Sphere
79 * @related /Graphics 3d/3D Sphere System
80 */
81 public class XylophoneApp extends Application {
82
83 private Timeline animation;
84 private Timeline animation2;
85
86 /*
87 * See JDK-8177428 for an explanation of why this is here.
88 */
89 private static AudioClip getNoteClip(String name) {
90 // First look for the clips in a directory next to our jar file
91 try {
92 // Get a URI to this class file
93 URI baseURI = XylophoneApp.class.getResource("XylophoneApp.class").toURI();
94
95 // If we have a jar URL, get the embedded http or file URL
96 // and trim off the internal jar path, this will leave us
97 // with a URL to the jar file
98 if (baseURI.getScheme().equals("jar")) {
99 String basePath = baseURI.getSchemeSpecificPart();
100 if (basePath.contains("!/")) {
101 basePath = basePath.substring(0, basePath.indexOf("!/"));
102 }
103 baseURI = new URI(basePath);
104 }
105
106 URL noteURL = baseURI.resolve("resources/"+name).toURL();
107
108 // check if the resource exists, then try to load it
109 if (noteURL.getProtocol().equals("http")) {
110 HttpURLConnection urlCon = (HttpURLConnection)noteURL.openConnection();
111 urlCon.setRequestMethod("HEAD");
112 urlCon.connect();
113 if (urlCon.getResponseCode() != HttpURLConnection.HTTP_OK) {
114 noteURL = null;
115 }
116 urlCon.disconnect();
117 } else if (noteURL.getProtocol().equals("file")) {
118 File f = new File(noteURL.getPath());
119 if (!f.exists() || !f.isFile()) {
120 noteURL = null;
121 }
122 } else {
123 // unsupported protocol
124 noteURL = null;
125 }
126 if (noteURL != null) {
127 return new AudioClip(noteURL.toExternalForm());
128 }
129 } catch (Exception e) {} // fail gracefully
130
131 // Fall back on the embedded clips
132 return new AudioClip(
133 AudioClipApp.class.getResource("/ensemble/samples/shared-resources/"+name).toExternalForm());
134 }
135
136 public Parent createContent() {
137 Xform sceneRoot = new Xform();
138 sceneRoot.rx.setAngle(45.0);
139 sceneRoot.ry.setAngle(30.0);
140 sceneRoot.setScale(2 * 1.5);
141
142 Group rectangleGroup = new Group();
143
144 double xStart = -110.0;
145 double xOffset = 30.0;
146 double yPos = 25.0;
147 double barWidth = 22.0;
148 double barDepth = 7.0;
149
150 // Base1
151 Box base1Cube = new Box(barWidth * 11.5, barDepth * 2.0, 10.0);
152 base1Cube.setMaterial(new PhongMaterial(new Color(0.2, 0.12, 0.1, 1.0)));
153 base1Cube.setTranslateX(xStart + 128);
154 base1Cube.setTranslateZ(yPos + 20.0);
155 base1Cube.setTranslateY(11.0);
156
157 // Base2
158 Box base2Cube = new Box(barWidth * 11.5, barDepth * 2.0, 10.0);
159 base2Cube.setMaterial(new PhongMaterial(new Color(0.2, 0.12, 0.1, 1.0)));
160 base2Cube.setTranslateX(xStart + 128);
161 base2Cube.setTranslateZ(yPos - 20.0);
162 base2Cube.setTranslateY(11.0);
163
164 Box[] barCubes = new Box[8];
165 Color[] colors = {
166 Color.PURPLE, Color.BLUEVIOLET, Color.BLUE, Color.GREEN,
167 Color.GREENYELLOW, Color.YELLOW, Color.ORANGE, Color.RED
168 };
169 for (int i = 0; i < barCubes.length; i++) {
170 final AudioClip barNote = getNoteClip("Note"+(i+1)+".wav");
171
172 barCubes[i] = new Box(barWidth, barDepth, 100.0 - (i * 5.0));
173 barCubes[i].setTranslateX(xStart + ((1 + i) * xOffset));
174 barCubes[i].setTranslateZ(yPos);
175 barCubes[i].setMaterial(new PhongMaterial(colors[i]));
176 barCubes[i].setOnMousePressed((MouseEvent me) -> {
177 barNote.play();
178 });
179 }
180
181 rectangleGroup.getChildren().addAll(base1Cube, base2Cube);
182 rectangleGroup.getChildren().addAll(java.util.Arrays.asList(barCubes));
183 sceneRoot.getChildren().add(rectangleGroup);
184
185 animation = new Timeline();
186 animation.getKeyFrames().addAll(new KeyFrame(Duration.ZERO,
187 new KeyValue(sceneRoot.ry.angleProperty(), 390d,
188 Interpolator.TANGENT(Duration.seconds(0.5), 390d,
189 Duration.seconds(0.5), 390d))),
190 new KeyFrame(Duration.seconds(2),
|