├── .gitignore ├── LICENSE.txt ├── README.md ├── arcgis-java-toolkit-examples ├── .gitignore ├── LICENSE.txt ├── README.md ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src │ └── main │ ├── java │ ├── com │ │ └── esri │ │ │ └── arcgisruntime │ │ │ └── toolkit │ │ │ └── examples │ │ │ ├── CompassExample.java │ │ │ ├── ExamplesApp.java │ │ │ ├── FloorFilterExample.java │ │ │ ├── UtilityNetworkTraceToolExample.java │ │ │ ├── controller │ │ │ ├── ExampleView.java │ │ │ └── ExamplesAppController.java │ │ │ ├── model │ │ │ └── Example.java │ │ │ └── utils │ │ │ └── ExampleUtils.java │ └── module-info.java │ └── resources │ └── com │ └── esri │ └── arcgisruntime │ └── toolkit │ └── examples │ ├── app.fxml │ ├── controller │ ├── example_view.fxml │ └── images │ │ ├── Compass.png │ │ ├── Floor Filter.png │ │ ├── Utility Network Trace.png │ │ └── default.png │ └── styles │ ├── app.css │ ├── example.css │ └── style.css └── arcgis-java-toolkit ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE.txt ├── README.md ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle └── src ├── integration-test ├── java │ └── com │ │ └── esri │ │ └── arcgisruntime │ │ └── toolkit │ │ └── FeatureTemplatePickerIntegrationTest.java └── resources │ └── hide-template-group-labels.css ├── main ├── java │ ├── com │ │ └── esri │ │ │ └── arcgisruntime │ │ │ └── toolkit │ │ │ ├── Compass.java │ │ │ ├── FeatureTemplateGroup.java │ │ │ ├── FeatureTemplateItem.java │ │ │ ├── FeatureTemplatePicker.java │ │ │ ├── FloorFilter.java │ │ │ ├── OverviewMap.java │ │ │ ├── Scalebar.java │ │ │ ├── ScalebarUtil.java │ │ │ ├── SketchEditorTemplateHelper.java │ │ │ ├── UtilityNetworkTraceOperationResult.java │ │ │ ├── UtilityNetworkTraceStartingPoint.java │ │ │ ├── UtilityNetworkTraceTool.java │ │ │ ├── UtilityNetworkTraceToolCompletedTrace.java │ │ │ ├── package-info.java │ │ │ └── skins │ │ │ ├── AlternatingBarScalebarSkin.java │ │ │ ├── BarScalebarSkin.java │ │ │ ├── CompassSkin.java │ │ │ ├── DualUnitScalebarSkin.java │ │ │ ├── FeatureTemplatePickerTilePaneSkin.java │ │ │ ├── FloorFilterSkin.java │ │ │ ├── GraduatedLineScalebarSkin.java │ │ │ ├── LineScaleBarSkin.java │ │ │ ├── OverviewMapSkin.java │ │ │ ├── ScalebarSkin.java │ │ │ ├── UtilityNetworkTraceOperationResultView.java │ │ │ ├── UtilityNetworkTraceSkin.java │ │ │ ├── UtilityNetworkTraceStartingPointView.java │ │ │ └── package-info.java │ └── module-info.java └── resources │ └── com │ └── esri │ └── arcgisruntime │ └── toolkit │ ├── feature-template-picker.css │ ├── floor-filter.css │ ├── skins │ └── utility_network_trace.fxml │ └── utility-network-trace.css └── test └── java └── com └── esri └── arcgisruntime └── toolkit ├── FeatureTemplateGroupUnitTest.java ├── FeatureTemplatePickerUnitTest.java ├── skins └── FeatureTemplatePickerTilePaneSkinUnitTest.java └── util └── PlatformUtils.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | # Compiled class file 4 | *.class 5 | 6 | # Log file 7 | *.log 8 | 9 | # BlueJ files 10 | *.ctxt 11 | 12 | # Mobile Tools for Java (J2ME) 13 | .mtj.tmp/ 14 | 15 | # Package Files # 16 | *.jar 17 | *.war 18 | *.ear 19 | *.zip 20 | *.tar.gz 21 | *.rar 22 | 23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 24 | hs_err_pid* 25 | 26 | /.idea/ 27 | /.gradle/ 28 | /build/ 29 | !/gradle/wrapper/gradle-wrapper.jar 30 | /out/ 31 | 32 | # OS generated files # 33 | ###################### 34 | .DS_Store 35 | .DS_Store? 36 | ._* 37 | .Spotlight-V100 38 | .Trashes 39 | ehthumbs.db 40 | /arcgis-runtime-samples-java.iws 41 | /arcgis-runtime-samples-java.iml -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License - 2.0 2 | 3 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 4 | 5 | 1. Definitions. 6 | 7 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 8 | 9 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 10 | 11 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control 12 | with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management 13 | of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial 14 | ownership of such entity. 15 | 16 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 17 | 18 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, 19 | and configuration files. 20 | 21 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to 22 | compiled object code, generated documentation, and conversions to other media types. 23 | 24 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice 25 | that is included in or attached to the work (an example is provided in the Appendix below). 26 | 27 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the 28 | editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes 29 | of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, 30 | the Work and Derivative Works thereof. 31 | 32 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work 33 | or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual 34 | or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of 35 | electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on 36 | electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for 37 | the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing 38 | by the copyright owner as "Not a Contribution." 39 | 40 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and 41 | subsequently incorporated within the Work. 42 | 43 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, 44 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, 45 | publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 46 | 47 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, 48 | non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, 49 | sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are 50 | necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was 51 | submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work 52 | or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You 53 | under this License for that Work shall terminate as of the date such litigation is filed. 54 | 55 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, 56 | and in Source or Object form, provided that You meet the following conditions: 57 | 58 | 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and 59 | 60 | 2. You must cause any modified files to carry prominent notices stating that You changed the files; and 61 | 62 | 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices 63 | from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 64 | 65 | 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a 66 | readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the 67 | Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the 68 | Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever 69 | such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. 70 | You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, 71 | provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to 72 | Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your 73 | modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with 74 | the conditions stated in this License. 75 | 76 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You 77 | to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, 78 | nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 79 | 80 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except 81 | as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 82 | 83 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides 84 | its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, 85 | any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for 86 | determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under 87 | this License. 88 | 89 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required 90 | by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, 91 | including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the 92 | use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or 93 | any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 94 | 95 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a 96 | fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting 97 | such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree 98 | to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your 99 | accepting any such warranty or additional liability. 100 | 101 | END OF TERMS AND CONDITIONS 102 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ArcGIS Maps SDK for Java Toolkit 2 | 3 | ## Introduction 4 | 5 | The ArcGIS Maps SDK for Java Toolkit contains controls and utilities to simplify your app development. The toolkit is provided as an open source resource (licensed under the Apache License Version 2.0), so you can feel free to download or clone the code and customize to meet your requirements. 6 | 7 | There are 2 projects within this repository: the Toolkit itself, `arcgis-java-toolkit`, and an Examples project, `arcgis-java-toolkit-examples`, which contains example implementations of the components to aid in your development. 8 | 9 | ## Resources 10 | 11 | * [ArcGIS Maps SDK for Java](https://developers.arcgis.com/java/) 12 | * [ArcGIS Maps SDKs for Native Apps Blog](https://community.esri.com/t5/arcgis-runtime-sdks-blog/bg-p/arcgis-runtime-sdks-blog) 13 | * [ArcGIS Blog](http://blogs.esri.com/esri/arcgis/) 14 | * [twitter@esri](http://twitter.com/esri) 15 | 16 | ## Issues 17 | 18 | Find a bug or want to request a new feature? Please let us know by submitting an issue. 19 | 20 | ## Contributing 21 | 22 | Esri welcomes contributions from anyone and everyone. Please see our [guidelines for contributing](https://github.com/esri/contributing). 23 | 24 | ## Licensing 25 | Copyright 2018-2022 Esri 26 | 27 | Licensed under the Apache License, Version 2.0 (the "License"); 28 | you may not use this file except in compliance with the License. 29 | You may obtain a copy of the License at 30 | 31 | http://www.apache.org/licenses/LICENSE-2.0 32 | 33 | Unless required by applicable law or agreed to in writing, software 34 | distributed under the License is distributed on an "AS IS" BASIS, 35 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 36 | See the License for the specific language governing permissions and 37 | limitations under the License. 38 | 39 | A copy of the license is available in the repository's [LICENSE.txt](LICENSE.txt) file. 40 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | # Compiled class file 4 | *.class 5 | 6 | # Log file 7 | *.log 8 | 9 | # BlueJ files 10 | *.ctxt 11 | 12 | # Mobile Tools for Java (J2ME) 13 | .mtj.tmp/ 14 | 15 | # Package Files # 16 | *.jar 17 | *.war 18 | *.ear 19 | *.zip 20 | *.tar.gz 21 | *.rar 22 | 23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 24 | hs_err_pid* 25 | 26 | /.idea/ 27 | /.gradle/ 28 | /build/ 29 | !/gradle/wrapper/gradle-wrapper.jar 30 | /out/ 31 | 32 | # OS generated files # 33 | ###################### 34 | .DS_Store 35 | .DS_Store? 36 | ._* 37 | .Spotlight-V100 38 | .Trashes 39 | ehthumbs.db 40 | /arcgis-runtime-samples-java.iws 41 | /arcgis-runtime-samples-java.iml 42 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/README.md: -------------------------------------------------------------------------------- 1 | # arcgis-java-toolkit-examples 2 | 3 | ## Introduction 4 | 5 | This project provides an Example App to view demo implementations of the ArcGIS Maps SDK for Java Toolkit components. 6 | 7 | ## Features 8 | 9 | - A main Example App run via Gradle for browsing through a demo of each of the components. 10 | - Additional optional settings for viewing and testing the capabilities of the components. 11 | - Individual Launcher Classes for each component to enable more efficient development and/or a more focused approach to viewing individual tools. 12 | 13 | ## Instructions 14 | 15 | The Example App requires the `arcgis-java-toolkit` project to run. The whole repository `arcgis-runtime-toolkit-java` must be cloned before following the below steps, ensuring the project directories for `arcgis-java-toolkit-examples` and `arcgis-java-toolkit` are next to each other. This enables straightforward testing of any amendments made to the toolkit components as you work. 16 | 17 | ### IntelliJ IDEA 18 | 19 | 1. Open Intellij IDEA and select File > Open.... 20 | 2. Select the `arcgis-runtime-toolkit-java` folder that you cloned, which contains both the `arcgis-java-toolkit` and `arcgis-java-toolkit-examples` projects. 21 | 3. Click OK. 22 | 4. Select File > Project Structure... and ensure that the Project SDK and language level are set to use Java 11. 23 | 5. Store your API key in the gradle.properties file located in the /.gradle folder within your home directory. The API key will be set as a Java system property when the sample is run. `apiKey = yourApiKey` 24 | 6. Open the Gradle view with View > Tool Windows > Gradle. 25 | 7. In the Gradle view, double-click the run task under Tasks > application to run the main Example App. 26 | Note: if you encounter the error `Could not get unknown property 'apiKey' for task ':run' of type org.gradle.api.tasks.JavaExec` you may have to set the Gradle user home in the IntelliJ Gradle settings to the /.gradle folder in your home directory, or may not have added your API key to your gradle.properties file. 27 | 8. An alternative to steps 6 and 7, is to run an individual demo by right-clicking on the Example class, e.g. `com.esri.arcgisruntime.toolkit.examples.CompassExample`, and selecting "Run CompassExample.main()". 28 | 29 | ### API Key requirements 30 | 31 | Some of the toolkit components utilize ArcGIS Platform services which require an API key. Refer to the 'Access services' section of the 32 | [Get Started guide](https://developers.arcgis.com/java/get-started/#3-access-services-and-content-with-an-api-key) 33 | for more information. Help with how to set your API key can be found in the 34 | [Developer Guide tutorials](https://developers.arcgis.com/java/maps-2d/tutorials/display-a-map/#set-your-api-key) 35 | and [Java Samples Repository](https://github.com/Esri/arcgis-runtime-samples-java). If a toolkit component requires an API 36 | key, this will be indicated within the JavaDoc for the component. 37 | 38 | ## Issues 39 | 40 | Find a bug or want to request a new feature? Please let us know by submitting an issue. 41 | 42 | ## Contributing 43 | 44 | Esri welcomes contributions from anyone and everyone. Please see our [guidelines for contributing](https://github.com/esri/contributing). 45 | 46 | ## Licensing 47 | 48 | Copyright 2018-2022 Esri 49 | 50 | Licensed under the Apache License, Version 2.0 (the "License"); 51 | you may not use this file except in compliance with the License. 52 | You may obtain a copy of the License at 53 | 54 | http://www.apache.org/licenses/LICENSE-2.0 55 | 56 | Unless required by applicable law or agreed to in writing, software 57 | distributed under the License is distributed on an "AS IS" BASIS, 58 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 59 | See the License for the specific language governing permissions and 60 | limitations under the License. 61 | 62 | A copy of the license is available in the repository's [LICENSE.txt](LICENSE.txt) file. 63 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'application' 3 | id 'org.openjfx.javafxplugin' version '0.0.13' 4 | } 5 | 6 | group = 'com.esri.arcgisruntime.toolkit.examples' 7 | 8 | ext { 9 | arcgisVersion = '200.0.0' 10 | } 11 | 12 | javafx { 13 | version = "17.0.2" 14 | modules = [ 'javafx.graphics', 'javafx.controls', 'javafx.fxml', 'javafx.web', 'javafx.media' ] 15 | } 16 | 17 | application { 18 | mainModule = "com.esri.arcgisruntime.toolkit.examples" 19 | mainClass = "com.esri.arcgisruntime.toolkit.examples.ExamplesApp" 20 | } 21 | 22 | compileJava.options.encoding = 'UTF-8' 23 | 24 | repositories { 25 | mavenCentral() 26 | maven { 27 | url 'https://esri.jfrog.io/artifactory/arcgis' 28 | } 29 | maven { 30 | url 'https://olympus.esri.com/artifactory/arcgisruntime-repo' 31 | } 32 | } 33 | 34 | configurations { 35 | natives 36 | } 37 | 38 | dependencies { 39 | implementation "com.esri.arcgisruntime:arcgis-java:$arcgisVersion" 40 | natives "com.esri.arcgisruntime:arcgis-java-jnilibs:$arcgisVersion" 41 | natives "com.esri.arcgisruntime:arcgis-java-resources:$arcgisVersion" 42 | // handle SLF4J http://www.slf4j.org/codes.html#StaticLoggerBinder 43 | runtimeOnly 'org.slf4j:slf4j-nop:1.7.32' 44 | implementation project(':arcgis-java-toolkit') 45 | } 46 | 47 | task createGradlePropertiesAndWriteApiKey { 48 | description = "Creates a new gradle.properties file with an empty API key variable in the user home ./gradle folder, if the file doesn't already exist." 49 | group = "build" 50 | def propertiesFile = new File("${System.properties.getProperty("user.home")}/.gradle/gradle.properties") 51 | if (!propertiesFile.exists()) { 52 | print("Go to " + new URL("https://developers.arcgis.com/dashboard") + " to get an API key.") 53 | print(" Add your API key to ${System.properties.getProperty("user.home")}\\.gradle\\gradle.properties.") 54 | propertiesFile.write("apiKey = ") 55 | } 56 | } 57 | 58 | task copyNatives(type: Copy) { 59 | description = "Copies the arcgis native libraries into the project build directory for development." 60 | group = "build" 61 | configurations.natives.asFileTree.each { 62 | from(zipTree(it)) 63 | } 64 | // store native libraries in a common location shared with other samples 65 | into "${System.properties.getProperty("user.home")}/.arcgis/$arcgisVersion" 66 | } 67 | 68 | run { 69 | doFirst { 70 | // sets the API key from the gradle.properties file as a Java system property 71 | systemProperty 'apiKey', apiKey 72 | } 73 | dependsOn copyNatives 74 | } 75 | 76 | task productionZip(type: Zip) { 77 | group = 'distribution' 78 | from copyNatives 79 | from jar.destinationDirectory 80 | into (project.name) 81 | archiveBaseName = project.name 82 | } 83 | 84 | wrapper { 85 | gradleVersion = '7.5.1' 86 | } 87 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Esri/arcgis-maps-sdk-java-toolkit/d74ab415c884fceaef37c155f6c7c6b5b54017ba/arcgis-java-toolkit-examples/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "arcgis-java-toolkit-examples" 2 | includeFlat 'arcgis-java-toolkit' 3 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/java/com/esri/arcgisruntime/toolkit/examples/ExamplesApp.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.examples; 18 | 19 | import com.esri.arcgisruntime.toolkit.examples.controller.ExamplesAppController; 20 | import javafx.application.Application; 21 | import javafx.fxml.FXMLLoader; 22 | import javafx.geometry.Rectangle2D; 23 | import javafx.scene.Parent; 24 | import javafx.scene.Scene; 25 | import javafx.stage.Screen; 26 | import javafx.stage.Stage; 27 | 28 | /** 29 | * The main application class for the ExamplesApp. The Controller Class is {@link ExamplesAppController}. 30 | * 31 | * @since 100.15.0 32 | */ 33 | public class ExamplesApp extends Application { 34 | 35 | private ExamplesAppController controller; 36 | 37 | @Override 38 | public void start(Stage primaryStage) { 39 | // loads the FXML 40 | FXMLLoader loader = new FXMLLoader(getClass().getResource("app.fxml")); 41 | try { 42 | Parent root = loader.load(); 43 | controller = loader.getController(); 44 | // sets the stage title 45 | primaryStage.setTitle("ArcGIS Maps SDK for Java Toolkit - Examples"); 46 | // on initial launch the stage is set to 75% of the screen size 47 | Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds(); 48 | primaryStage.setWidth(screenBounds.getWidth() * 0.75); 49 | primaryStage.setHeight(screenBounds.getHeight() * .75); 50 | 51 | // configures the scene and sets it to the stage 52 | var scene = new Scene(root); 53 | // individual stylesheets can be commented out for testing purposes 54 | scene.getStylesheets().add(String.valueOf(getClass().getResource("styles/style.css"))); 55 | scene.getStylesheets().add(String.valueOf(getClass().getResource("styles/app.css"))); 56 | scene.getStylesheets().add(String.valueOf(getClass().getResource("styles/example.css"))); 57 | primaryStage.setScene(scene); 58 | primaryStage.show(); 59 | } catch (Exception e) { 60 | e.printStackTrace(); 61 | } 62 | } 63 | 64 | public static void main(String[] args) { 65 | launch(args); 66 | } 67 | 68 | @Override 69 | public void stop() { 70 | controller.terminate(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/java/com/esri/arcgisruntime/toolkit/examples/FloorFilterExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.examples; 18 | 19 | import com.esri.arcgisruntime.mapping.ArcGISMap; 20 | import com.esri.arcgisruntime.mapping.view.GeoView; 21 | import com.esri.arcgisruntime.mapping.view.MapView; 22 | import com.esri.arcgisruntime.toolkit.FloorFilter; 23 | import com.esri.arcgisruntime.toolkit.examples.model.Example; 24 | import com.esri.arcgisruntime.toolkit.examples.utils.ExampleUtils; 25 | import javafx.application.Application; 26 | import javafx.scene.Node; 27 | import javafx.scene.control.*; 28 | import javafx.scene.layout.BorderPane; 29 | import javafx.scene.layout.VBox; 30 | import javafx.stage.Stage; 31 | 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | /** 36 | * An Example Class for the {@link FloorFilter} Toolkit Component. Implements the {@link Example} interface to ensure 37 | * required methods are implemented. The example can be viewed by running the 38 | * {@link ExamplesApp}, or as a standalone app via {@link FloorFilterExample}. 39 | * 40 | * @since 100.15.0 41 | */ 42 | public class FloorFilterExample extends Application implements Example { 43 | 44 | // a MapView and a FloorFilter to be used on the MapView 45 | private final MapView mapView = new MapView(); 46 | private final FloorFilter floorFilter; 47 | 48 | // the required UI components 49 | private final List tabs = new ArrayList<>(); 50 | private final VBox settings; 51 | private final BorderPane borderPane; 52 | 53 | /** 54 | * A constructor for the FloorFilterExample that demonstrates how to implement a FloorFilter for a MapView. 55 | * 56 | * A Tab is created for the view to display in the application and settings are configured for testing and demo 57 | * purposes. 58 | * 59 | * @since 100.15.0 60 | */ 61 | public FloorFilterExample() { 62 | // configure mapview tab 63 | ArcGISMap map = new ArcGISMap("https://www.arcgis.com/home/item.html?id=f133a698536f44c8884ad81f80b6cfc7"); 64 | mapView.setMap(map); 65 | borderPane = new BorderPane(); 66 | // instantiate a FloorFilter passing in the MapView 67 | floorFilter = new FloorFilter(mapView); 68 | // configure the UI for displaying the FloorFilter and MapView 69 | // here the FloorFilter is displayed in a BorderPane alongside the MapView 70 | floorFilter.minHeightProperty().bind(borderPane.heightProperty()); 71 | borderPane.setLeft(floorFilter); 72 | borderPane.setCenter(mapView); 73 | Tab mapViewTab = ExampleUtils.createTab(borderPane, "Map"); 74 | 75 | // add the tab to the list 76 | tabs.add(mapViewTab); 77 | 78 | // configure settings options 79 | settings = configureSettings(); 80 | } 81 | 82 | /** 83 | * Sets up the required UI elements for toggling properties and other settings relating to the Toolkit Component. 84 | * 85 | * For the FloorFilter this includes AutomaticSelectionMode, size and position. 86 | * 87 | * @return a VBox containing the settings 88 | * @since 100.15.0 89 | */ 90 | private VBox configureSettings() { 91 | // define specific settings for the FloorFilter 92 | List requiredSettings = new ArrayList<>(); 93 | 94 | // automatic selection mode 95 | VBox autoSelectVBox = new VBox(5); 96 | Label autoSelectLabel = new Label("Automatic selection mode:"); 97 | ComboBox autoSelectComboBox = new ComboBox<>(); 98 | autoSelectComboBox.getItems().addAll(FloorFilter.AutomaticSelectionMode.ALWAYS, 99 | FloorFilter.AutomaticSelectionMode.ALWAYS_NON_CLEARING, FloorFilter.AutomaticSelectionMode.NEVER); 100 | autoSelectComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { 101 | floorFilter.setAutomaticSelectionMode(newValue); 102 | }); 103 | autoSelectComboBox.getSelectionModel().select(FloorFilter.AutomaticSelectionMode.ALWAYS); 104 | autoSelectVBox.getChildren().addAll(autoSelectLabel, autoSelectComboBox); 105 | requiredSettings.add(autoSelectVBox); 106 | 107 | // Layout settings 108 | TitledPane layoutTitledPane = new TitledPane(); 109 | layoutTitledPane.setExpanded(false); 110 | layoutTitledPane.setText("Layout settings"); 111 | VBox layoutVBox = new VBox(5); 112 | layoutTitledPane.setContent(layoutVBox); 113 | // resize 114 | Label sizeLabel = new Label("Resize:"); 115 | Slider sizeSlider = new Slider(120, 500, 220); 116 | sizeSlider.setShowTickLabels(true); 117 | sizeSlider.setMajorTickUnit(500); 118 | sizeSlider.valueProperty().addListener((observable, oldValue, newValue) -> { 119 | floorFilter.setPrefSize(newValue.doubleValue(), newValue.doubleValue()); 120 | }); 121 | layoutVBox.getChildren().addAll(sizeLabel, sizeSlider); 122 | // position 123 | Label positionLabel = new Label("Re-position:"); 124 | ComboBox positionComboBox = new ComboBox<>(); 125 | positionComboBox.getItems().addAll("Left", "Right"); 126 | positionComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { 127 | if(newValue.equals("Left")) { 128 | borderPane.setRight(null); 129 | borderPane.setLeft(floorFilter); 130 | } else { 131 | borderPane.setLeft(null); 132 | borderPane.setRight(floorFilter); 133 | } 134 | }); 135 | positionComboBox.getSelectionModel().select("Left"); 136 | layoutVBox.getChildren().addAll(positionLabel, positionComboBox); 137 | requiredSettings.add(layoutTitledPane); 138 | 139 | // return a fully configured VBox of the settings 140 | return ExampleUtils.createSettings(getName(), requiredSettings); 141 | } 142 | 143 | @Override 144 | public String getName() {return "Floor Filter";} 145 | 146 | @Override 147 | public String getDescription() { 148 | return "Shows sites and facilities, and enables toggling the visibility of levels on floor aware maps and scenes."; 149 | } 150 | 151 | @Override 152 | public VBox getSettings() { 153 | return settings; 154 | } 155 | 156 | @Override 157 | public List getTabs() { 158 | return tabs; 159 | } 160 | 161 | @Override 162 | public List getGeoViews() { 163 | return List.of(mapView); 164 | } 165 | 166 | @Override 167 | public void start(Stage primaryStage) { 168 | // sets up the individual stage if run via the Launcher class 169 | ExampleUtils.setupIndividualExampleStage(primaryStage, this); 170 | } 171 | 172 | public static void main(String[] args) { 173 | // configure the API Key 174 | // authentication with an API key or named user is required to access basemaps and other location services 175 | ExampleUtils.configureAPIKeyForRunningStandAloneExample(); 176 | Application.launch(args); } 177 | 178 | @Override 179 | public void stop() { 180 | mapView.dispose(); 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/java/com/esri/arcgisruntime/toolkit/examples/controller/ExampleView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.examples.controller; 18 | 19 | import com.esri.arcgisruntime.toolkit.examples.model.Example; 20 | import javafx.beans.property.SimpleObjectProperty; 21 | import javafx.fxml.FXML; 22 | import javafx.fxml.FXMLLoader; 23 | import javafx.scene.control.ScrollPane; 24 | import javafx.scene.control.TabPane; 25 | import javafx.scene.control.ToggleButton; 26 | import javafx.scene.layout.BorderPane; 27 | 28 | /** 29 | * A custom BorderPane used to display an example either within the Example App or as a standalone via the individual 30 | * component Application. The layout is configured via example_view.fxml. 31 | * 32 | * @since 100.15.0 33 | */ 34 | public class ExampleView extends BorderPane { 35 | 36 | private final SimpleObjectProperty selectedExampleProperty = new SimpleObjectProperty<>(); 37 | @FXML private ScrollPane settingsScrollPane; 38 | @FXML private TabPane exampleTabPane; 39 | @FXML private ToggleButton settingsButton; 40 | 41 | /** 42 | * Constructor for the ExampleView. Loads the FXML file and sets the controller. Configures properties for the view. 43 | * 44 | * @since 100.15.0 45 | */ 46 | public ExampleView() { 47 | // load the FXML file 48 | FXMLLoader loader = new FXMLLoader(getClass().getResource("example_view.fxml")); 49 | loader.setRoot(this); 50 | loader.setController(this); 51 | try { 52 | loader.load(); 53 | 54 | // when a new example is selected, update the UI to display it 55 | selectedExampleProperty.addListener(((observable, oldValue, newValue) -> { 56 | // configure the tab pane to contain all tabs associated with the newly selected example 57 | exampleTabPane.getTabs().clear(); 58 | if (newValue.getTabs() != null) { 59 | exampleTabPane.getTabs().addAll(newValue.getTabs()); 60 | } 61 | // configure the settings pane but hide it initially 62 | settingsScrollPane.setContent(newValue.getSettings()); 63 | this.setRight(null); 64 | settingsButton.selectedProperty().set(false); 65 | })); 66 | 67 | // configure the settings button to show/hide the settings pane 68 | settingsButton.selectedProperty().addListener(((observable, oldValue, newValue) -> { 69 | if (settingsButton.isSelected()) { 70 | settingsButton.setText("Hide Settings"); 71 | this.setRight(settingsScrollPane); 72 | } else { 73 | settingsButton.setText("Show Settings"); 74 | this.setRight(null); 75 | } 76 | })); 77 | } catch (Exception e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | 82 | /** 83 | * Sets the selected example to the selected example property. 84 | * 85 | * @param selectedExample the example to be set 86 | * @since 100.15.0 87 | */ 88 | public void setSelectedExample(Example selectedExample) { 89 | selectedExampleProperty.set(selectedExample); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/java/com/esri/arcgisruntime/toolkit/examples/controller/ExamplesAppController.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.examples.controller; 18 | 19 | import com.esri.arcgisruntime.ArcGISRuntimeEnvironment; 20 | import com.esri.arcgisruntime.mapping.view.GeoView; 21 | import com.esri.arcgisruntime.toolkit.examples.ExamplesApp; 22 | import com.esri.arcgisruntime.toolkit.examples.CompassExample; 23 | import com.esri.arcgisruntime.toolkit.examples.FloorFilterExample; 24 | import com.esri.arcgisruntime.toolkit.examples.UtilityNetworkTraceToolExample; 25 | import com.esri.arcgisruntime.toolkit.examples.model.Example; 26 | import javafx.fxml.FXML; 27 | import javafx.geometry.Pos; 28 | import javafx.scene.control.ComboBox; 29 | import javafx.scene.control.Label; 30 | import javafx.scene.control.ListCell; 31 | import javafx.scene.image.Image; 32 | import javafx.scene.image.ImageView; 33 | import javafx.scene.layout.GridPane; 34 | import javafx.scene.layout.HBox; 35 | import javafx.scene.layout.Region; 36 | import javafx.scene.layout.VBox; 37 | import javafx.util.StringConverter; 38 | 39 | import java.util.ArrayList; 40 | import java.util.List; 41 | 42 | /** 43 | * A Controller for the {@link ExamplesApp}. This includes a header section with ComboBox 44 | * menu to select an Example to view, and also includes an initial Landing Page that displays when the app first loads 45 | * giving an overview of the available Examples in a GridPane layout. 46 | * 47 | * @since 100.15.0 48 | */ 49 | public class ExamplesAppController { 50 | 51 | private final List examples = new ArrayList<>(); 52 | @FXML private ComboBox menu; 53 | @FXML private ExampleView exampleView; 54 | @FXML private GridPane examplesGridPane; 55 | @FXML private VBox landingPage; 56 | 57 | /** 58 | * Sets up and populates the UI. 59 | * 60 | * @since 100.15.0 61 | */ 62 | public void initialize() { 63 | // authentication with an API key or named user is required to access basemaps and other location services 64 | ArcGISRuntimeEnvironment.setApiKey(System.getProperty("apiKey")); 65 | 66 | // adds all the examples to the UI 67 | examples.addAll(getExamples()); 68 | examples.forEach(example -> menu.getItems().add(example)); 69 | // displays the examples by name in the menu 70 | menu.setConverter(new StringConverter<>() { 71 | @Override 72 | public String toString(Example example) { 73 | if (example == null) { 74 | return null; 75 | } else { 76 | return example.getName(); 77 | } 78 | } 79 | @Override 80 | public Example fromString(String string) { 81 | return null; 82 | } 83 | }); 84 | // displays a checkmark in the menu on the selected item via CSS 85 | menu.setCellFactory(lv -> { 86 | final ListCell cell = new ListCell<>() { 87 | @Override 88 | public void updateItem(Example item, boolean empty) { 89 | super.updateItem(item, empty); 90 | setText(item != null ? item.getName() : null); 91 | } 92 | }; 93 | Region icon = new Region(); 94 | icon.getStyleClass().add("icon"); 95 | cell.setGraphic(icon); 96 | cell.setGraphicTextGap(20); 97 | return cell; 98 | }); 99 | 100 | // sets the selected example to the view 101 | menu.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { 102 | if (landingPage.isVisible()) { 103 | // hide the landing page once a selection is made 104 | landingPage.setVisible(false); 105 | } 106 | exampleView.setSelectedExample(newValue); 107 | }); 108 | // toggles the visibility of the landing page and example view 109 | exampleView.visibleProperty().bind(landingPage.visibleProperty().not()); 110 | // configures the grid pane of examples on the landing page 111 | setupExampleGridPane(); 112 | } 113 | 114 | /** 115 | * Returns a list of Examples. 116 | * 117 | * @return the list of examples 118 | * @since 100.15.0 119 | */ 120 | private List getExamples() { 121 | Example compassExample = new CompassExample(); 122 | Example floorFilterExample = new FloorFilterExample(); 123 | Example utilityNetworkTraceToolExample = new UtilityNetworkTraceToolExample(); 124 | return List.of(compassExample, floorFilterExample, utilityNetworkTraceToolExample); 125 | } 126 | 127 | /** 128 | * Setups up the GridPane of examples displayed on the landing page. This is a 2 column grid with as many rows 129 | * as is required for the number of examples. The GridPane is setup in app.fxml. 130 | * 131 | * @since 100.15.0 132 | */ 133 | private void setupExampleGridPane() { 134 | var numberOfColumns = 2; 135 | var indexOfExample = 0; 136 | // add each of the examples into the grid at the appropriate column and row 137 | while (indexOfExample < examples.size()) { 138 | int row = indexOfExample / numberOfColumns; 139 | int col = indexOfExample % numberOfColumns; 140 | var example = examples.get(indexOfExample); 141 | // HBox container for each example 142 | HBox hbox = new HBox(15); 143 | hbox.getStyleClass().add("arcgis-toolkit-java-panel"); 144 | hbox.getStyleClass().add("arcgis-toolkit-java-panel-white"); 145 | hbox.setId("example-grid-pane-item"); 146 | hbox.setAlignment(Pos.CENTER_LEFT); 147 | // on clicking the HBox the example will be selected 148 | hbox.setOnMouseClicked(e -> menu.getSelectionModel().select(example)); 149 | // ImageView displays thumbnail of the component 150 | ImageView imageView = new ImageView(); 151 | imageView.setFitWidth(100); 152 | imageView.setFitHeight(100); 153 | // check if an image exists for the example and display the default if not 154 | if (ExamplesAppController.class.getResource("images/" + example.getName() + ".png") != null) { 155 | imageView.setImage(new Image(String.valueOf(ExamplesAppController.class.getResource("images/" + example.getName() + ".png")))); 156 | } else if (ExamplesAppController.class.getResource("images/default.png") != null){ 157 | imageView.setImage(new Image(String.valueOf(ExamplesAppController.class.getResource("images/default.png")))); 158 | } 159 | // VBox containing the name and description for the example 160 | var labelVBox = new VBox(8); 161 | labelVBox.getStyleClass().add( 162 | "arcgis-toolkit-java-panel-no-padding, arcgis-toolkit-java-panel-no-border, arcgis-toolkit-java-panel-white"); 163 | labelVBox.setAlignment(Pos.CENTER_LEFT); 164 | var componentName = new Label(example.getName()); 165 | componentName.getStyleClass().add("arcgis-toolkit-java-h2"); 166 | componentName.getStyleClass().add("arcgis-toolkit-java-blue-text"); 167 | var componentDescription = new Label(example.getDescription()); 168 | labelVBox.getChildren().addAll(componentName, componentDescription); 169 | // add child components to the HBox 170 | hbox.getChildren().addAll(imageView, labelVBox); 171 | // add the example to the GridPane 172 | examplesGridPane.add(hbox, col, row); 173 | // increment the index to loop through the next example 174 | indexOfExample += 1; 175 | } 176 | } 177 | 178 | /** 179 | * Disposes the views for each example on termination. 180 | * 181 | * @since 100.15.0 182 | */ 183 | public void terminate() { 184 | examples.forEach(example -> example.getGeoViews().forEach(GeoView::dispose)); 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/java/com/esri/arcgisruntime/toolkit/examples/model/Example.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.examples.model; 18 | 19 | import com.esri.arcgisruntime.mapping.view.GeoView; 20 | import com.esri.arcgisruntime.toolkit.examples.controller.ExampleView; 21 | import javafx.scene.control.Tab; 22 | import javafx.scene.layout.VBox; 23 | 24 | import java.util.List; 25 | 26 | /** 27 | * Defines methods that are required for all Examples that are displayed within an 28 | * {@link ExampleView}. 29 | * 30 | * @since 100.15.0 31 | */ 32 | public interface Example { 33 | 34 | /** 35 | * Returns the name of the Toolkit Component used in the Example. E.g. Compass. 36 | * 37 | * @return a String of the name 38 | * @since 100.15.0 39 | */ 40 | String getName(); 41 | 42 | /** 43 | * Returns a description of the Toolkit Component used in the Example. 44 | * 45 | * @return a String of the description 46 | * @since 100.15.0 47 | */ 48 | String getDescription(); 49 | 50 | /** 51 | * Returns a list of Tabs used to display the views required for the Example. 52 | * 53 | * @return a list of Tabs 54 | * @since 100.15.0 55 | */ 56 | List getTabs(); 57 | 58 | /** 59 | * Returns a VBox containing any settings configured for the Example. 60 | * 61 | * @return a VBox containing any required settings 62 | * @since 100.15.0 63 | */ 64 | VBox getSettings(); 65 | 66 | /** 67 | * Returns any GeoViews used for the Example. This list may contain one or both of a MapView and a SceneView, or 68 | * in some cases may not contain either if the Toolkit Component does not require a GeoView. 69 | * 70 | * @return a list of GeoViews 71 | * @since 100.15.0 72 | */ 73 | List getGeoViews(); 74 | } 75 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/java/com/esri/arcgisruntime/toolkit/examples/utils/ExampleUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.examples.utils; 18 | 19 | import com.esri.arcgisruntime.ArcGISRuntimeEnvironment; 20 | import com.esri.arcgisruntime.toolkit.examples.controller.ExampleView; 21 | import com.esri.arcgisruntime.toolkit.examples.model.Example; 22 | import javafx.geometry.Pos; 23 | import javafx.geometry.Rectangle2D; 24 | import javafx.scene.Node; 25 | import javafx.scene.Scene; 26 | import javafx.scene.control.Label; 27 | import javafx.scene.control.Tab; 28 | import javafx.scene.layout.StackPane; 29 | import javafx.scene.layout.VBox; 30 | import javafx.stage.Screen; 31 | import javafx.stage.Stage; 32 | 33 | import java.io.FileInputStream; 34 | import java.util.List; 35 | import java.util.Properties; 36 | import java.util.logging.Logger; 37 | 38 | /** 39 | * Defines util methods to support the configuration of Examples that are displayed within an 40 | * {@link ExampleView}. 41 | * 42 | * @since 100.15.0 43 | */ 44 | public class ExampleUtils { 45 | 46 | /** 47 | * Creates a Tab from the provided Node and label and sets the required configuration. 48 | * 49 | * @param node the node to display in the Tab 50 | * @param tabLabel the String to display on the tab 51 | * @return the configured Tab 52 | * @since 100.15.0 53 | */ 54 | public static Tab createTab(Node node, String tabLabel) { 55 | Tab tab = new Tab(); 56 | // set the provided node as the tabs content 57 | tab.setContent(node); 58 | // set the tab text as the provided label 59 | tab.setText(tabLabel); 60 | // prevent the tab from being closed 61 | tab.setClosable(false); 62 | return tab; 63 | } 64 | 65 | /** 66 | * Creates a VBox containing the provided settings and sets all the required configuration for consistency. 67 | * 68 | * @param exampleName the name of the example 69 | * @param settings a list of the Nodes used to create the settings for the specific example 70 | * @return the configured VBox 71 | * @since 100.15.0 72 | */ 73 | public static VBox createSettings(String exampleName, List settings) { 74 | // configure the VBox 75 | VBox vBox = new VBox(10); 76 | vBox.getStyleClass().add("settings"); 77 | vBox.setAlignment(Pos.TOP_LEFT); 78 | // set a heading using the example name 79 | Label label = new Label(exampleName + " Settings"); 80 | label.getStyleClass().add("arcgis-toolkit-java-h3"); 81 | vBox.getChildren().add(label); 82 | // for each provided setting add a styleclass and add to the VBox 83 | settings.forEach(node -> { 84 | node.getStyleClass().add("individual-setting"); 85 | vBox.getChildren().add(node); 86 | }); 87 | return vBox; 88 | } 89 | 90 | /** 91 | * Used to configure the JavaFX Stage when the Example is run directly via the Launcher Class. 92 | * 93 | * @param primaryStage the stage 94 | * @param example the example 95 | * @since 100.15.0 96 | */ 97 | public static void setupIndividualExampleStage(Stage primaryStage, Example example) { 98 | // add the ExampleView to a StackPane 99 | StackPane stackPane = new StackPane(); 100 | ExampleView exampleView = new ExampleView(); 101 | exampleView.setSelectedExample(example); 102 | stackPane.getChildren().add(exampleView); 103 | 104 | // set the stage title 105 | primaryStage.setTitle("ArcGIS Maps SDK for Java Toolkit Examples - " + example.getName()); 106 | // initially launch the stage at 75% of the screen size 107 | Rectangle2D screenBounds = Screen.getPrimary().getVisualBounds(); 108 | primaryStage.setWidth(screenBounds.getWidth() * 0.75); 109 | primaryStage.setHeight(screenBounds.getHeight() * .75); 110 | // configure the Scene and add to the Stage 111 | var scene = new Scene(stackPane); 112 | // individual stylesheets can be commented out for testing purposes 113 | scene.getStylesheets().add("/com/esri/arcgisruntime/toolkit/examples/styles/example.css"); 114 | scene.getStylesheets().add("/com/esri/arcgisruntime/toolkit/examples/styles/style.css"); 115 | primaryStage.setScene(scene); 116 | primaryStage.show(); 117 | } 118 | 119 | /** 120 | * Used to configure the API Key when the Example is run directly via the Launcher Class. This must be called before 121 | * the app is launched. 122 | * 123 | * Note: it is not best practice to store API keys in source code. 124 | * An API key is required to enable access to services, web maps, and web scenes hosted in ArcGIS Online. 125 | * If you haven't already, go to your developer dashboard to get your API key. 126 | * Please refer to 127 | * https://developers.arcgis.com/java/get-started/ 128 | * for more information. 129 | * 130 | * @since 100.15.0 131 | */ 132 | public static void configureAPIKeyForRunningStandAloneExample() { 133 | // configure warning message to provide details about API Keys if required 134 | var logger = Logger.getLogger(ExampleUtils.class.getName()); 135 | var apiKeyWarning = "An API key is required to enable access to services, web maps, and web scenes hosted in " + 136 | "ArcGIS Online.\n If you haven't already, go to your developer dashboard to get your API key.\n Please " + 137 | "refer to https://developers.arcgis.com/java/get-started/ for more information.\nYou can set your API " + 138 | "Key in ExampleUtils or add an apiKey property to " + 139 | System.getProperty("user.home") + "\\.gradle\\gradle.properties.\n Note: it is not best practice to " + 140 | "store API keys in source code."; 141 | try { 142 | // loads the gradle.properties file 143 | Properties prop = new Properties(); 144 | prop.load(new FileInputStream(System.getProperty("user.home") + "/.gradle/gradle.properties")); 145 | // set the API Key 146 | // Note: it is not best practice to store API keys in source code 147 | ArcGISRuntimeEnvironment.setApiKey(prop.getProperty("apiKey")); 148 | 149 | if (prop.getProperty("apiKey") == null) { 150 | // if the API Key is not configured correctly in the gradle.properties file, display the warning message 151 | logger.warning(apiKeyWarning); 152 | } 153 | } catch (Exception e) { 154 | logger.warning("Exception details: " + e.getMessage() + apiKeyWarning); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | module com.esri.arcgisruntime.toolkit.examples { 17 | // require ArcGIS Maps SDK for Java module 18 | requires com.esri.arcgisruntime; 19 | // require ArcGIS Maps SDK for Java toolkit module 20 | requires com.esri.arcgisruntime.toolkit; 21 | // require JavaFX modules the application uses 22 | requires javafx.graphics; 23 | requires javafx.controls; 24 | requires javafx.fxml; 25 | 26 | // require other modules the application uses 27 | requires java.logging; 28 | 29 | exports com.esri.arcgisruntime.toolkit.examples; 30 | exports com.esri.arcgisruntime.toolkit.examples.controller; 31 | exports com.esri.arcgisruntime.toolkit.examples.utils; 32 | // allow FXML module access to Example FXML files 33 | opens com.esri.arcgisruntime.toolkit.examples to javafx.fxml; 34 | opens com.esri.arcgisruntime.toolkit.examples.controller to javafx.fxml; 35 | } 36 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/app.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
45 |
46 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/controller/example_view.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 |
25 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/controller/images/Compass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Esri/arcgis-maps-sdk-java-toolkit/d74ab415c884fceaef37c155f6c7c6b5b54017ba/arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/controller/images/Compass.png -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/controller/images/Floor Filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Esri/arcgis-maps-sdk-java-toolkit/d74ab415c884fceaef37c155f6c7c6b5b54017ba/arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/controller/images/Floor Filter.png -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/controller/images/Utility Network Trace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Esri/arcgis-maps-sdk-java-toolkit/d74ab415c884fceaef37c155f6c7c6b5b54017ba/arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/controller/images/Utility Network Trace.png -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/controller/images/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Esri/arcgis-maps-sdk-java-toolkit/d74ab415c884fceaef37c155f6c7c6b5b54017ba/arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/controller/images/default.png -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/styles/app.css: -------------------------------------------------------------------------------- 1 | /* Stylesheet containing specific styles for the Examples App */ 2 | 3 | /* Colors and themes taken from Esri Calcite Web */ 4 | /* https://esri.github.io/calcite-web */ 5 | * { 6 | -calcite-ui-brand: #007AC2; 7 | -calcite-ui-brand-hover: #00619B; 8 | -calcite-ui-brand-press: #004874; 9 | -calcite-ui-background: #F8F8F8; 10 | -calcite-ui-foreground-1: #FFFFFF; 11 | -calcite-ui-foreground-2: #F3F3F3; 12 | -calcite-ui-foreground-3: #EAEAEA; 13 | -calcite-ui-text-1: #151515; 14 | -calcite-ui-text-2: #4A4A4A; 15 | -calcite-ui-text-3: #6A6A6A; 16 | -calcite-ui-text-inverse: #FFFFFF; 17 | -calcite-ui-text-link: #00619B; 18 | -calcite-ui-border-1: #CACACA; 19 | -calcite-ui-border-2: #D4D4D4; 20 | -calcite-ui-border-3: #DFDFDF; 21 | -calcite-ui-border-input: #949494; 22 | -calcite-ui-info: #00619B; /* state color: blue - Info - used for Non critical information which requires minimal user attention */ 23 | -calcite-ui-success: #35AC46; /* state color: green - Success - To be used when an important action has been completed successfully and requires user notification. */ 24 | -calcite-ui-warning: #EDD317; /* state color: yellow - Warning - To be used when something needs the user's attention, but is not critical or destructive.*/ 25 | -calcite-ui-danger: #D83020; /* state color: red - Danger - A connection error, destructive action, action failure, etc. */ 26 | -calcite-ui-danger-hover: #A82B1E; 27 | -calcite-ui-danger-press: #7C1D13; 28 | } 29 | 30 | /* The menu combo box in app header */ 31 | 32 | #menu { 33 | -fx-min-height:35; 34 | -fx-min-width: 300; 35 | -fx-font-size: 16; 36 | } 37 | 38 | #menu .combo-box-popup .list-view .list-cell { 39 | -fx-cell-size: 45; 40 | } 41 | 42 | #menu .combo-box-popup .list-view .list-cell .icon { 43 | -fx-min-width: 10; 44 | -fx-pref-width: 10; 45 | -fx-max-width: 10; 46 | -fx-min-height: 10; 47 | -fx-pref-height: 10; 48 | -fx-max-height: 10; 49 | -fx-shape: "M448,71.9c-17.3-13.4-41.5-9.3-54.1,9.1L214,344.2l-99.1-107.3c-14.6-16.6-39.1-17.4-54.7-1.8 c-15.6,15.5-16.4,41.6-1.7,58.1c0,0,120.4,133.6,137.7,147c17.3,13.4,41.5,9.3,54.1-9.1l206.3-301.7 C469.2,110.9,465.3,85.2,448,71.9z"; 50 | -fx-background-color: white; 51 | } 52 | 53 | #menu .combo-box-popup .list-view .list-cell:filled:selected { 54 | -fx-content-display: left; 55 | } 56 | 57 | /* The landing page grid pane */ 58 | 59 | #example-grid-pane-item:hover { 60 | -fx-cursor:hand; 61 | -fx-border-color: -calcite-ui-brand-hover; 62 | } 63 | -------------------------------------------------------------------------------- /arcgis-java-toolkit-examples/src/main/resources/com/esri/arcgisruntime/toolkit/examples/styles/example.css: -------------------------------------------------------------------------------- 1 | /* Stylesheet containing specific styles for an Example View */ 2 | 3 | /* Colors and themes taken from Esri Calcite Web */ 4 | * { 5 | -calcite-ui-brand: #007AC2; 6 | -calcite-ui-brand-hover: #00619B; 7 | -calcite-ui-brand-press: #004874; 8 | -calcite-ui-background: #F8F8F8; 9 | -calcite-ui-foreground-1: #FFFFFF; 10 | -calcite-ui-foreground-2: #F3F3F3; 11 | -calcite-ui-foreground-3: #EAEAEA; 12 | -calcite-ui-text-1: #151515; 13 | -calcite-ui-text-2: #4A4A4A; 14 | -calcite-ui-text-3: #6A6A6A; 15 | -calcite-ui-text-inverse: #FFFFFF; 16 | -calcite-ui-text-link: #00619B; 17 | -calcite-ui-border-1: #CACACA; 18 | -calcite-ui-border-2: #D4D4D4; 19 | -calcite-ui-border-3: #DFDFDF; 20 | -calcite-ui-border-input: #949494; 21 | -calcite-ui-info: #00619B; /* state color: blue - Info - used for Non critical information which requires minimal user attention */ 22 | -calcite-ui-success: #35AC46; /* state color: green - Success - To be used when an important action has been completed successfully and requires user notification. */ 23 | -calcite-ui-warning: #EDD317; /* state color: yellow - Warning - To be used when something needs the user's attention, but is not critical or destructive.*/ 24 | -calcite-ui-danger: #D83020; /* state color: red - Danger - A connection error, destructive action, action failure, etc. */ 25 | -calcite-ui-danger-hover: #A82B1E; 26 | -calcite-ui-danger-press: #7C1D13; 27 | } 28 | 29 | /* Example tab pane */ 30 | 31 | #example-tab-pane { 32 | -fx-tab-min-width: 100; 33 | -fx-tab-min-height: 30; 34 | } 35 | 36 | /* Settings */ 37 | 38 | .settings { 39 | -fx-padding: 10 10 10 10; 40 | -fx-border-style: hidden hidden hidden solid; 41 | -fx-border-color: -calcite-ui-border-input; 42 | -fx-border-width: 2; 43 | -fx-background-color: -calcite-ui-background; 44 | } 45 | 46 | .individual-setting { 47 | -fx-padding: 5; 48 | -fx-border-style: hidden; 49 | -fx-border-color: transparent; 50 | -fx-background-color: -calcite-ui-foreground-3; 51 | } 52 | 53 | .individual-setting Label { 54 | -fx-wrap-text: true; 55 | } 56 | 57 | .color-picker { 58 | -fx-min-height: 35; 59 | -fx-max-width: Infinity; 60 | } 61 | 62 | .color-picker .arrow-button { 63 | -fx-padding: 10; 64 | } 65 | 66 | .titled-pane > .title { 67 | -fx-font-size: 16; 68 | } 69 | 70 | /* Other styles */ 71 | 72 | .example-stackpane { 73 | -fx-border-color: black; 74 | -fx-border-width: 1; 75 | -fx-border-style: solid hidden hidden hidden; 76 | } 77 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Java template 3 | # Compiled class file 4 | *.class 5 | 6 | # Log file 7 | *.log 8 | 9 | # BlueJ files 10 | *.ctxt 11 | 12 | # Mobile Tools for Java (J2ME) 13 | .mtj.tmp/ 14 | 15 | # Package Files # 16 | *.jar 17 | *.war 18 | *.ear 19 | *.zip 20 | *.tar.gz 21 | *.rar 22 | 23 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 24 | hs_err_pid* 25 | 26 | /.idea/ 27 | /.gradle/ 28 | /build/ 29 | !/gradle/wrapper/gradle-wrapper.jar 30 | /out/ 31 | 32 | # OS generated files # 33 | ###################### 34 | .DS_Store 35 | .DS_Store? 36 | ._* 37 | .Spotlight-V100 38 | .Trashes 39 | ehthumbs.db 40 | /arcgis-runtime-samples-java.iws 41 | /arcgis-runtime-samples-java.iml 42 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Esri welcomes contributions from anyone and everyone. Please see our [guidelines for contributing](https://github.com/esri/contributing). 2 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License - 2.0 2 | 3 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 4 | 5 | 1. Definitions. 6 | 7 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 8 | 9 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 10 | 11 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control 12 | with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management 13 | of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial 14 | ownership of such entity. 15 | 16 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 17 | 18 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, 19 | and configuration files. 20 | 21 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to 22 | compiled object code, generated documentation, and conversions to other media types. 23 | 24 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice 25 | that is included in or attached to the work (an example is provided in the Appendix below). 26 | 27 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the 28 | editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes 29 | of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, 30 | the Work and Derivative Works thereof. 31 | 32 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work 33 | or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual 34 | or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of 35 | electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on 36 | electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for 37 | the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing 38 | by the copyright owner as "Not a Contribution." 39 | 40 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and 41 | subsequently incorporated within the Work. 42 | 43 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, 44 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, 45 | publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 46 | 47 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, 48 | non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, 49 | sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are 50 | necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was 51 | submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work 52 | or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You 53 | under this License for that Work shall terminate as of the date such litigation is filed. 54 | 55 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, 56 | and in Source or Object form, provided that You meet the following conditions: 57 | 58 | 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and 59 | 60 | 2. You must cause any modified files to carry prominent notices stating that You changed the files; and 61 | 62 | 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices 63 | from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 64 | 65 | 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a 66 | readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the 67 | Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the 68 | Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever 69 | such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. 70 | You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, 71 | provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to 72 | Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your 73 | modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with 74 | the conditions stated in this License. 75 | 76 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You 77 | to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, 78 | nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 79 | 80 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except 81 | as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 82 | 83 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides 84 | its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, 85 | any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for 86 | determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under 87 | this License. 88 | 89 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required 90 | by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, 91 | including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the 92 | use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or 93 | any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 94 | 95 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a 96 | fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting 97 | such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree 98 | to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your 99 | accepting any such warranty or additional liability. 100 | 101 | END OF TERMS AND CONDITIONS 102 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/README.md: -------------------------------------------------------------------------------- 1 | # arcgis-java-toolkit 2 | 3 | ## Introduction 4 | 5 | The ArcGIS Maps SDK for Java Toolkit contains controls and utilities to simplify your app development. The toolkit is provided as an open source resource (licensed under the Apache License Version 2.0), so you can feel free to download or clone the code and customize to meet your requirements. 6 | 7 | ## Features 8 | 9 | The latest version of the ArcGIS Maps SDK for Java Toolkit features the following JavaFX components: 10 | 11 | - Compass: Shows the current viewpoint heading. Can be clicked to reorient the view to north. 12 | - Feature Template Picker: Shows feature templates for a collection of feature layers. 13 | - Floor Filter: Shows sites and facilities, and enables toggling the visibility of levels on floor aware maps and scenes. 14 | - Overview Map: Indicates the viewpoint of the main map/scene view. 15 | - Scalebar: Shows a ruler with units proportional to the map's current scale. 16 | - Utility Network Trace Tool: Use named trace configurations defined in a web map to perform connected trace operations and compare results. 17 | 18 | ## Requirements 19 | 20 | The toolkit requires the ArcGIS Maps SDK for Java. Refer to the 'Instructions' section below if you are using Gradle. 21 | See [the developer guide](https://developers.arcgis.com/java/install-and-set-up/) for complete instructions and 22 | getting setup with the SDK. 23 | 24 | The following table shows the minimum version of the SDK compatible with the toolkit: 25 | 26 | | SDK Version | Toolkit Version | 27 | |-------------|-----------------| 28 | | 100.2.1 | 100.2.1 | 29 | | 100.14.0 | 100.14.0 | 30 | | 100.15.0 | 100.15.0 | 31 | | 200.0.0 | 200.0.0 | 32 | 33 | ### API Key requirements 34 | 35 | Some of the toolkit components utilize ArcGIS Location Services which require an API key. Refer to the 'Get an access token' section of the [Get Started guide](https://developers.arcgis.com/java/get-started/#3-get-an-access-token) for more information. Help with how to set your API key can be found in the 36 | [Developer Guide tutorials](https://developers.arcgis.com/java/maps-2d/tutorials/display-a-map/#set-your-api-key) 37 | and [Java Samples Repository](https://github.com/Esri/arcgis-runtime-samples-java). If a toolkit component requires an API 38 | key, this will be indicated within the JavaDoc for the component. 39 | 40 | ## Instructions 41 | 42 | The toolkit library jar is hosted on https://esri.jfrog.io/artifactory/arcgis. 43 | 44 | To add the dependency to your project, include the following in your Gradle script: 45 | ```groovy 46 | implementation 'com.esri.arcgisruntime:arcgis-java-toolkit:200.0.0' 47 | ``` 48 | 49 | The toolkit is open source (licensed under the Apache License Version 2.0), so you are also free to clone or download this repository, customize to meet your requirements, and then build and deploy using Gradle. 50 | 51 | ## Issues 52 | 53 | Find a bug or want to request a new feature? Please let us know by submitting an issue. 54 | 55 | ## Contributing 56 | 57 | Esri welcomes contributions from anyone and everyone. Please see our [guidelines for contributing](https://github.com/esri/contributing). 58 | 59 | ## Licensing 60 | Copyright 2018-2022 Esri 61 | 62 | Licensed under the Apache License, Version 2.0 (the "License"); 63 | you may not use this file except in compliance with the License. 64 | You may obtain a copy of the License at 65 | 66 | http://www.apache.org/licenses/LICENSE-2.0 67 | 68 | Unless required by applicable law or agreed to in writing, software 69 | distributed under the License is distributed on an "AS IS" BASIS, 70 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 71 | See the License for the specific language governing permissions and 72 | limitations under the License. 73 | 74 | A copy of the license is available in the repository's [LICENSE.txt](LICENSE.txt) file. 75 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "java-library" 3 | id "idea" 4 | id "eclipse" 5 | id 'org.openjfx.javafxplugin' version '0.0.13' 6 | id "com.jfrog.artifactory" version "4.26.1" 7 | id "maven-publish" 8 | } 9 | 10 | javafx { 11 | version = "17.0.2" 12 | modules = [ 'javafx.graphics', 'javafx.controls', 'javafx.fxml', 'javafx.web', 'javafx.media' ] 13 | } 14 | 15 | group = GROUP 16 | // if VERSION property is not set via gradle, default to test 17 | version = project.findProperty("VERSION") ?: "9999" 18 | archivesBaseName = "arcgis-java-toolkit" 19 | 20 | idea.module.downloadJavadoc = true 21 | eclipse.classpath.downloadJavadoc = true 22 | 23 | compileJava.options.encoding = 'UTF-8' 24 | 25 | repositories { 26 | mavenCentral() 27 | maven { 28 | url = 'https://esri.jfrog.io/artifactory/arcgis' 29 | } 30 | maven { 31 | url = 'https://olympus.esri.com/artifactory/arcgisruntime-repo' 32 | } 33 | } 34 | 35 | sourceSets { 36 | integrationTest { 37 | java.srcDirs = ['src/integration-test/java'] 38 | compileClasspath += sourceSets.main.output + configurations.testRuntimeClasspath 39 | resources.srcDirs = ["src/integration-test/resources"] 40 | runtimeClasspath += output + compileClasspath 41 | } 42 | } 43 | 44 | dependencies { 45 | implementation "com.esri.arcgisruntime:arcgis-java:$SDKVERSION" 46 | 47 | testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0") 48 | testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0") 49 | 50 | testImplementation "org.testfx:testfx-core:4.0.15-alpha" 51 | testImplementation "org.testfx:testfx-junit5:4.0.15-alpha" 52 | } 53 | 54 | task integrationTest(type: Test) { 55 | description = 'Runs the integration tests.' 56 | group = 'verification' 57 | testClassesDirs = sourceSets.integrationTest.output.classesDirs 58 | classpath = sourceSets.integrationTest.runtimeClasspath 59 | } 60 | 61 | tasks.withType(Test.class) { 62 | useJUnitPlatform() 63 | } 64 | 65 | task javadocJar(type: Jar) { 66 | dependsOn javadoc 67 | description = "Creates a javadoc jar." 68 | group = "Documentation" 69 | archiveClassifier.set('javadoc') 70 | from javadoc.destinationDir 71 | } 72 | 73 | // do not generate a .module file 74 | tasks.withType(GenerateModuleMetadata) { 75 | enabled = false 76 | } 77 | 78 | publishing { 79 | publications { 80 | mavenJava(MavenPublication) { 81 | artifactId = archivesBaseName 82 | from components.java 83 | pom { 84 | licenses { 85 | license { 86 | name = 'Esri License Agreement, E204' 87 | url = 'http://www.esri.com/~/media/Files/Pdfs/legal/pdfs/mla_e204_e300/english' 88 | distribution = 'repo' 89 | } 90 | } 91 | // remove JavaFX dependencies 92 | withXml { 93 | asNode().dependencies.'*'.findAll() { 94 | it.groupId.text() == 'org.openjfx' 95 | }.each { 96 | it.parent().remove(it) 97 | } 98 | } 99 | } 100 | } 101 | } 102 | } 103 | 104 | artifactory { 105 | contextUrl = ARTIFACTORY_URL 106 | publish { 107 | repository { 108 | repoKey = REPO_KEY 109 | username = ARTIFACTORY_USER 110 | password = ARTIFACTORY_PASSWORD 111 | } 112 | defaults { 113 | publications('mavenJava') 114 | } 115 | } 116 | resolve { 117 | repoKey = 'arcgisruntime-repo' 118 | } 119 | } 120 | 121 | // This wrapper task is only used if this project is the root project not if it is a subproject e.g. of an app project 122 | if (rootProject == project) { 123 | wrapper { 124 | gradleVersion = '7.5.1' 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/gradle.properties: -------------------------------------------------------------------------------- 1 | # used in build script 2 | # can edit manually here or override via command line e.g. -PSDKVERSION=100.14.0 3 | SDKVERSION=200.0.0 4 | GROUP=com.esri.arcgisruntime 5 | ARTIFACTORY_URL=https://olympus.esri.com/artifactory 6 | ARTIFACTORY_USER 7 | ARTIFACTORY_PASSWORD 8 | REPO_KEY 9 | # additional version property for testing purposes 10 | VERSION 11 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Esri/arcgis-maps-sdk-java-toolkit/d74ab415c884fceaef37c155f6c7c6b5b54017ba/arcgis-java-toolkit/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /arcgis-java-toolkit/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit 84 | 85 | APP_NAME="Gradle" 86 | APP_BASE_NAME=${0##*/} 87 | 88 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 89 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 90 | 91 | # Use the maximum available, or set MAX_FD != -1 to use that value. 92 | MAX_FD=maximum 93 | 94 | warn () { 95 | echo "$*" 96 | } >&2 97 | 98 | die () { 99 | echo 100 | echo "$*" 101 | echo 102 | exit 1 103 | } >&2 104 | 105 | # OS specific support (must be 'true' or 'false'). 106 | cygwin=false 107 | msys=false 108 | darwin=false 109 | nonstop=false 110 | case "$( uname )" in #( 111 | CYGWIN* ) cygwin=true ;; #( 112 | Darwin* ) darwin=true ;; #( 113 | MSYS* | MINGW* ) msys=true ;; #( 114 | NONSTOP* ) nonstop=true ;; 115 | esac 116 | 117 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 118 | 119 | 120 | # Determine the Java command to use to start the JVM. 121 | if [ -n "$JAVA_HOME" ] ; then 122 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 123 | # IBM's JDK on AIX uses strange locations for the executables 124 | JAVACMD=$JAVA_HOME/jre/sh/java 125 | else 126 | JAVACMD=$JAVA_HOME/bin/java 127 | fi 128 | if [ ! -x "$JAVACMD" ] ; then 129 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 130 | 131 | Please set the JAVA_HOME variable in your environment to match the 132 | location of your Java installation." 133 | fi 134 | else 135 | JAVACMD=java 136 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | 142 | # Increase the maximum file descriptors if we can. 143 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 144 | case $MAX_FD in #( 145 | max*) 146 | MAX_FD=$( ulimit -H -n ) || 147 | warn "Could not query maximum file descriptor limit" 148 | esac 149 | case $MAX_FD in #( 150 | '' | soft) :;; #( 151 | *) 152 | ulimit -n "$MAX_FD" || 153 | warn "Could not set maximum file descriptor limit to $MAX_FD" 154 | esac 155 | fi 156 | 157 | # Collect all arguments for the java command, stacking in reverse order: 158 | # * args from the command line 159 | # * the main class name 160 | # * -classpath 161 | # * -D...appname settings 162 | # * --module-path (only if needed) 163 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 164 | 165 | # For Cygwin or MSYS, switch paths to Windows format before running java 166 | if "$cygwin" || "$msys" ; then 167 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 168 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 169 | 170 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 171 | 172 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 173 | for arg do 174 | if 175 | case $arg in #( 176 | -*) false ;; # don't mess with options #( 177 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 178 | [ -e "$t" ] ;; #( 179 | *) false ;; 180 | esac 181 | then 182 | arg=$( cygpath --path --ignore --mixed "$arg" ) 183 | fi 184 | # Roll the args list around exactly as many times as the number of 185 | # args, so each arg winds up back in the position where it started, but 186 | # possibly modified. 187 | # 188 | # NB: a `for` loop captures its iteration list before it begins, so 189 | # changing the positional parameters here affects neither the number of 190 | # iterations, nor the values presented in `arg`. 191 | shift # remove old arg 192 | set -- "$@" "$arg" # push replacement arg 193 | done 194 | fi 195 | 196 | # Collect all arguments for the java command; 197 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 198 | # shell script including quotes and variable substitutions, so put them in 199 | # double quotes to make sure that they get re-expanded; and 200 | # * put everything else in single quotes, so that it's not re-expanded. 201 | 202 | set -- \ 203 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 204 | -classpath "$CLASSPATH" \ 205 | org.gradle.wrapper.GradleWrapperMain \ 206 | "$@" 207 | 208 | # Use "xargs" to parse quoted args. 209 | # 210 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 211 | # 212 | # In Bash we could simply go: 213 | # 214 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 215 | # set -- "${ARGS[@]}" "$@" 216 | # 217 | # but POSIX shell has neither arrays nor command substitution, so instead we 218 | # post-process each arg (as a line of input to sed) to backslash-escape any 219 | # character that might be a shell metacharacter, then use eval to reverse 220 | # that process (while maintaining the separation between arguments), and wrap 221 | # the whole thing up as a single "set" statement. 222 | # 223 | # This will of course break if any of these variables contains a newline or 224 | # an unmatched quote. 225 | # 226 | 227 | eval "set -- $( 228 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 229 | xargs -n1 | 230 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 231 | tr '\n' ' ' 232 | )" '"$@"' 233 | 234 | exec "$JAVACMD" "$@" 235 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = "arcgis-java-toolkit" 2 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/integration-test/resources/hide-template-group-labels.css: -------------------------------------------------------------------------------- 1 | .feature-template-group > .label { 2 | visibility: hidden; 3 | } 4 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/FeatureTemplateGroup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit; 18 | 19 | import com.esri.arcgisruntime.data.ArcGISFeatureTable; 20 | import com.esri.arcgisruntime.data.FeatureTemplate; 21 | import com.esri.arcgisruntime.layers.FeatureLayer; 22 | import com.esri.arcgisruntime.loadable.LoadStatus; 23 | import javafx.beans.property.ReadOnlyListProperty; 24 | import javafx.beans.property.ReadOnlyListWrapper; 25 | import javafx.beans.property.ReadOnlyObjectProperty; 26 | import javafx.beans.property.ReadOnlyObjectWrapper; 27 | import javafx.collections.FXCollections; 28 | import javafx.collections.ObservableList; 29 | 30 | import java.util.Objects; 31 | import java.util.stream.Collectors; 32 | import java.util.stream.Stream; 33 | 34 | /** 35 | * Model class representing a group of feature templates belonging to a specific feature layer. 36 | * 37 | * @since 100.7.0 38 | */ 39 | public final class FeatureTemplateGroup { 40 | 41 | private final ReadOnlyObjectWrapper featureLayer; 42 | private final ReadOnlyListWrapper featureTemplateItems; 43 | 44 | /** 45 | * Creates a new instance based on the given feature layer. No feature template items will be created for the group 46 | * if the feature layer's feature table is not an instance of {@link ArcGISFeatureTable}. 47 | * 48 | * @param featureLayer the feature layer 49 | * @throws NullPointerException if feature layer is null 50 | * @since 100.7.0 51 | */ 52 | FeatureTemplateGroup(FeatureLayer featureLayer) { 53 | this.featureLayer = new ReadOnlyObjectWrapper<>(Objects.requireNonNull(featureLayer)); 54 | this.featureTemplateItems = new ReadOnlyListWrapper<>(FXCollections.observableArrayList()); 55 | 56 | featureLayer.loadAsync(); 57 | featureLayer.addDoneLoadingListener(() -> { 58 | if (featureLayer.getLoadStatus() == LoadStatus.LOADED && 59 | featureLayer.getFeatureTable() instanceof ArcGISFeatureTable) { 60 | ArcGISFeatureTable arcGISFeatureTable = (ArcGISFeatureTable) featureLayer.getFeatureTable(); 61 | Stream featureTemplateStream = arcGISFeatureTable.getFeatureTemplates().stream(); 62 | Stream featureTemplateTypesTemplateStream = arcGISFeatureTable.getFeatureTypes().stream() 63 | .flatMap(ft -> ft.getTemplates().stream()); 64 | featureTemplateItems.addAll(Stream.concat(featureTemplateStream, featureTemplateTypesTemplateStream) 65 | .map(ft -> new FeatureTemplateItem(featureLayer, ft)) 66 | .collect(Collectors.toList())); 67 | } 68 | }); 69 | } 70 | 71 | /** 72 | * Gets the associated feature layer. 73 | * 74 | * @return the feature layer 75 | * @since 100.7.0 76 | */ 77 | public FeatureLayer getFeatureLayer() { 78 | return featureLayerProperty().get(); 79 | } 80 | 81 | /** 82 | * The associated feature layer. 83 | * 84 | * @return feature layer read-only property 85 | * @since 100.7.0 86 | */ 87 | public ReadOnlyObjectProperty featureLayerProperty() { 88 | return featureLayer.getReadOnlyProperty(); 89 | } 90 | 91 | /** 92 | * Gets the feature template items belonging to this group. 93 | * 94 | * @return read-only list of feature template items in the group 95 | * @since 100.7.0 96 | */ 97 | public ObservableList getFeatureTemplateItems() { 98 | return featureTemplateItems.get(); 99 | } 100 | 101 | /** 102 | * The feature template items belonging to this group. 103 | * 104 | * @return feature template items read-only list property 105 | * @since 100.7.0 106 | */ 107 | public ReadOnlyListProperty featureTemplateItemsProperty() { 108 | return featureTemplateItems.getReadOnlyProperty(); 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/FeatureTemplateItem.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit; 18 | 19 | import com.esri.arcgisruntime.data.FeatureTemplate; 20 | import com.esri.arcgisruntime.layers.FeatureLayer; 21 | import javafx.beans.property.ReadOnlyObjectProperty; 22 | import javafx.beans.property.ReadOnlyObjectWrapper; 23 | 24 | /** 25 | * Model class for representing a feature template with the context of its feature layer. 26 | * 27 | * @since 100.7.0 28 | */ 29 | public final class FeatureTemplateItem { 30 | 31 | private final ReadOnlyObjectProperty featureLayer; 32 | private final ReadOnlyObjectProperty featureTemplate; 33 | 34 | /** 35 | * Creates an instance for the given feature layer and feature template. 36 | * 37 | * @param featureLayer the feature layer 38 | * @param featureTemplate the feature template 39 | * @since 100.7.0 40 | */ 41 | FeatureTemplateItem(FeatureLayer featureLayer, FeatureTemplate featureTemplate) { 42 | this.featureLayer = new ReadOnlyObjectWrapper<>(featureLayer); 43 | this.featureTemplate = new ReadOnlyObjectWrapper<>(featureTemplate); 44 | } 45 | 46 | /** 47 | * Gets the associated feature layer. 48 | * 49 | * @return feature layer 50 | * @since 100.7.0 51 | */ 52 | public FeatureLayer getFeatureLayer() { 53 | return featureLayer.get(); 54 | } 55 | 56 | /** 57 | * The associated feature layer. 58 | * 59 | * @return feature layer read-only property 60 | * @since 100.7.0 61 | */ 62 | public ReadOnlyObjectProperty featureLayerProperty() { 63 | return featureLayer; 64 | } 65 | 66 | /** 67 | * Gets the associated feature template. 68 | * 69 | * @return feature template 70 | * @since 100.7.0 71 | */ 72 | public FeatureTemplate getFeatureTemplate() { 73 | return featureTemplate.get(); 74 | } 75 | 76 | /** 77 | * The associated feature template. 78 | * 79 | * @return feature template read-only property. 80 | * @since 100.7.0 81 | */ 82 | public ReadOnlyObjectProperty featureTemplateProperty() { 83 | return featureTemplate; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/OverviewMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit; 18 | 19 | import java.util.Objects; 20 | 21 | import com.esri.arcgisruntime.mapping.Basemap; 22 | import com.esri.arcgisruntime.mapping.BasemapStyle; 23 | import com.esri.arcgisruntime.mapping.view.GeoView; 24 | import com.esri.arcgisruntime.mapping.view.MapView; 25 | import com.esri.arcgisruntime.symbology.ColorUtil; 26 | import com.esri.arcgisruntime.symbology.FillSymbol; 27 | import com.esri.arcgisruntime.symbology.MarkerSymbol; 28 | import com.esri.arcgisruntime.symbology.SimpleFillSymbol; 29 | import com.esri.arcgisruntime.symbology.SimpleLineSymbol; 30 | import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol; 31 | import com.esri.arcgisruntime.symbology.Symbol; 32 | import com.esri.arcgisruntime.toolkit.skins.OverviewMapSkin; 33 | import javafx.beans.property.ReadOnlyObjectProperty; 34 | import javafx.beans.property.SimpleDoubleProperty; 35 | import javafx.beans.property.SimpleObjectProperty; 36 | import javafx.scene.control.Control; 37 | import javafx.scene.control.Skin; 38 | import javafx.scene.paint.Color; 39 | 40 | /** 41 | * An overview map control that indicates the viewpoint of another map or scene view. 42 | * 43 | * Note: By default, the OverviewMap will attempt to use an ArcGIS Topographic basemap, which requires an 44 | * API key 45 | * to access. 46 | * 47 | * @since 100.2.1 48 | */ 49 | public class OverviewMap extends Control { 50 | 51 | final static private FillSymbol FILL_SYMBOL = 52 | new SimpleFillSymbol(SimpleFillSymbol.Style.SOLID, Color.TRANSPARENT, 53 | new SimpleLineSymbol(SimpleLineSymbol.Style.SOLID, Color.RED, 1.0f)); 54 | final static private MarkerSymbol MARKER_SYMBOL = 55 | new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CROSS, Color.RED, 20); 56 | 57 | final private SimpleObjectProperty geoViewProperty = new SimpleObjectProperty<>(); 58 | final private SimpleObjectProperty basemapProperty = new SimpleObjectProperty<>(); 59 | final private SimpleObjectProperty symbolProperty = new SimpleObjectProperty<>(); 60 | final private SimpleDoubleProperty scaleFactorProperty = new SimpleDoubleProperty(25.0); 61 | 62 | /** 63 | * Creates an overview map for a GeoView using default values for the basemap and indicator symbol. 64 | * 65 | * Note: By default, the OverviewMap will attempt to use an ArcGIS Topographic basemap, which requires an 66 | * API key 67 | * to access. 68 | * 69 | * @param geoView the GeoView to connect to this overview map 70 | * @throws NullPointerException if geoView is null 71 | * @since 100.2.1 72 | */ 73 | public OverviewMap(GeoView geoView) { 74 | this(geoView, new Basemap(BasemapStyle.ARCGIS_TOPOGRAPHIC), geoView instanceof MapView ? FILL_SYMBOL : MARKER_SYMBOL); 75 | } 76 | 77 | /** 78 | * Creates an overview map for a GeoView using a default indicator symbol. 79 | * 80 | * @param geoView the GeoView to connect to this overview map 81 | * @param basemap the basemap 82 | * @throws NullPointerException if geoView is null 83 | * @throws NullPointerException if basemap is null 84 | * @since 100.2.1 85 | */ 86 | public OverviewMap(GeoView geoView, Basemap basemap) { 87 | this(geoView, basemap, geoView instanceof MapView ? FILL_SYMBOL : MARKER_SYMBOL); 88 | } 89 | 90 | /** 91 | * Creates an overview map for a GeoView using a default basemap. 92 | * 93 | * Note: By default, the OverviewMap will attempt to use an ArcGIS Topographic basemap, which requires an 94 | * API key 95 | * to access. 96 | * 97 | * @param geoView the GeoView to connect to this overview map 98 | * @param symbol the symbol to use, for a map view use a fill symbol and for a scene view use a marker symbol 99 | * @throws NullPointerException if geoView is null 100 | * @throws NullPointerException if symbol is null 101 | * @since 100.2.1 102 | */ 103 | public OverviewMap(GeoView geoView, Symbol symbol) { 104 | this(geoView, new Basemap(BasemapStyle.ARCGIS_TOPOGRAPHIC), symbol); 105 | } 106 | 107 | /** 108 | * Creates an overview map for a GeoView. 109 | * 110 | * @param geoView the GeoView to connect to this overview map 111 | * @param basemap the basemap 112 | * @param symbol the symbol to use, for a map view use a fill symbol and for a scene view use a marker symbol 113 | * @throws NullPointerException if geoView is null 114 | * @throws NullPointerException if basemap is null 115 | * @throws NullPointerException if symbol is null 116 | * @since 100.2.1 117 | */ 118 | public OverviewMap(GeoView geoView, Basemap basemap, Symbol symbol) { 119 | geoViewProperty.set(Objects.requireNonNull(geoView, "geoView cannot be null")); 120 | basemapProperty.set(Objects.requireNonNull(basemap, "basemap cannot be null")); 121 | symbolProperty.set(Objects.requireNonNull(symbol, "symbol cannot be null")); 122 | 123 | setMaxHeight(USE_PREF_SIZE); 124 | setMaxWidth(USE_PREF_SIZE); 125 | setMinHeight(USE_PREF_SIZE); 126 | setMinWidth(USE_PREF_SIZE); 127 | } 128 | 129 | @Override 130 | protected Skin createDefaultSkin() { 131 | return new OverviewMapSkin(this); 132 | } 133 | 134 | /** 135 | * Gets the GeoView that this overview map is linked to. 136 | * 137 | * @return the GeoView 138 | * @since 100.2.1 139 | */ 140 | public GeoView getGeoView() { 141 | return geoViewProperty.get(); 142 | } 143 | 144 | /** 145 | * A readonly property containing the GeoView linked to this overview map. 146 | * 147 | * @return the GeoView property 148 | * @since 100.2.1 149 | */ 150 | public ReadOnlyObjectProperty geoViewProperty() { 151 | return geoViewProperty; 152 | } 153 | 154 | /** 155 | * Gets the basemap being used. 156 | * 157 | * @return the basemap 158 | * @since 100.2.1 159 | */ 160 | public Basemap getBasemap() { 161 | return basemapProperty.get(); 162 | } 163 | 164 | /** 165 | * Sets the basemap to use. 166 | * 167 | * @param basemap the basemap to use 168 | * @since 100.2.1 169 | */ 170 | public void setBasemap(Basemap basemap) { 171 | basemapProperty.set(basemap); 172 | } 173 | 174 | /** 175 | * A property containing the basemap being used in this overview map. 176 | * 177 | * @return the basemap 178 | * @since 100.2.1 179 | */ 180 | public SimpleObjectProperty basemapProperty() { 181 | return basemapProperty; 182 | } 183 | 184 | /** 185 | * Gets the symbol being used to indicate the viewpoint. 186 | * 187 | * @return the symbol 188 | * @since 100.2.1 189 | */ 190 | public Symbol getSymbol() { 191 | return symbolProperty.get(); 192 | } 193 | 194 | /** 195 | * Sets the symbol to use to indicate the viewpoint. 196 | * 197 | * @param symbol the symbol, for a mapview use a fill symbol and for a scene view use a marker symbol 198 | * @since 100.2.1 199 | */ 200 | public void setSymbol(Symbol symbol) { 201 | symbolProperty.set(symbol); 202 | } 203 | 204 | /** 205 | * A property containing the symbol being used in this overview map. 206 | * 207 | * @return the symbol property 208 | * @since 100.2.1 209 | */ 210 | public SimpleObjectProperty symbolProperty() { 211 | return symbolProperty; 212 | } 213 | 214 | /** 215 | * A property containing the amount to scale the OverviewMap compared to the geoView. The default is 25.0. 216 | * 217 | * @return the scale property 218 | * @since 100.14.0 219 | */ 220 | public SimpleDoubleProperty scaleFactorProperty() { 221 | return scaleFactorProperty; 222 | } 223 | 224 | /** 225 | * Sets the value used to scale the OverviewMap compared to the geoView. The default is 25.0. 226 | * 227 | * @param scaleFactor the scale factor to set 228 | * @since 100.14.0 229 | */ 230 | public void setScaleFactor(double scaleFactor) { 231 | scaleFactorProperty.set(scaleFactor); 232 | } 233 | 234 | /** 235 | * Gets the value used to scale the OverviewMap compared to the geoView. The default is 25.0. 236 | * 237 | * @return the scale factor 238 | * @since 100.14.0 239 | */ 240 | public double getScaleFactor() { 241 | return scaleFactorProperty.get(); 242 | } 243 | } 244 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/SketchEditorTemplateHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit; 18 | 19 | import java.util.Objects; 20 | 21 | import com.esri.arcgisruntime.data.FeatureTemplate; 22 | import com.esri.arcgisruntime.geometry.GeometryType; 23 | import com.esri.arcgisruntime.layers.FeatureLayer; 24 | import com.esri.arcgisruntime.mapping.view.Graphic; 25 | import com.esri.arcgisruntime.mapping.view.SketchCreationMode; 26 | import com.esri.arcgisruntime.mapping.view.SketchStyle; 27 | import com.esri.arcgisruntime.symbology.FillSymbol; 28 | import com.esri.arcgisruntime.symbology.LineSymbol; 29 | import com.esri.arcgisruntime.symbology.MarkerSymbol; 30 | import com.esri.arcgisruntime.symbology.MultilayerPointSymbol; 31 | import com.esri.arcgisruntime.symbology.MultilayerPolygonSymbol; 32 | import com.esri.arcgisruntime.symbology.MultilayerPolylineSymbol; 33 | import com.esri.arcgisruntime.symbology.MultilayerSymbol; 34 | import com.esri.arcgisruntime.symbology.Symbol; 35 | 36 | /** 37 | * A helper class to create a SketchStyle and a SketchCreationMode for a FeatureTemplate. 38 | * 39 | * @since 100.5.0 40 | */ 41 | public final class SketchEditorTemplateHelper { 42 | 43 | /** 44 | * Creates a sketch creation mode that best matches the template. 45 | * 46 | * @param featureTemplate the feature template 47 | * @param featureLayer the feature layer the template will be used with 48 | * @return the sketch creation mode 49 | * @throws NullPointerException if featureTemplate is null 50 | * @throws NullPointerException if featureLayer is null 51 | * @since 100.5.0 52 | */ 53 | public static SketchCreationMode createsSketchCreationMode(FeatureTemplate featureTemplate, FeatureLayer featureLayer) { 54 | GeometryType geometryType = Objects.requireNonNull(featureLayer, "featureLayer").getFeatureTable().getGeometryType(); 55 | FeatureTemplate.DrawingTool drawingTool = Objects.requireNonNull(featureTemplate, "featureTemplate").getDrawingTool(); 56 | 57 | // creation mode 58 | SketchCreationMode creationMode; 59 | switch (drawingTool) { 60 | case FREEHAND: 61 | switch (geometryType) { 62 | case POLYGON: 63 | creationMode = SketchCreationMode.FREEHAND_POLYGON; 64 | break; 65 | case POLYLINE: 66 | creationMode = SketchCreationMode.FREEHAND_LINE; 67 | break; 68 | default: 69 | throw new RuntimeException(geometryType.name() + " is not supported"); 70 | } 71 | break; 72 | case LINE: 73 | creationMode = SketchCreationMode.POLYLINE; 74 | break; 75 | case POINT: 76 | switch (geometryType) { 77 | case POINT: 78 | creationMode = SketchCreationMode.POINT; 79 | break; 80 | case MULTIPOINT: 81 | creationMode = SketchCreationMode.MULTIPOINT; 82 | break; 83 | default: 84 | throw new RuntimeException(geometryType.name() + " is not supported"); 85 | } 86 | break; 87 | case POLYGON: 88 | creationMode = SketchCreationMode.POLYGON; 89 | break; 90 | default: 91 | throw new RuntimeException(drawingTool.name() + " is not supported"); 92 | } 93 | 94 | return creationMode; 95 | } 96 | 97 | /** 98 | * Creates a sketch style suitable for the feature template and feature layer. 99 | * 100 | * @param featureTemplate the feature template 101 | * @param featureLayer the feature layer the template will be used with 102 | * @return the sketch style 103 | * @throws NullPointerException if featureTemplate is null 104 | * @throws NullPointerException if featureLayer is null 105 | * @since 100.5.0 106 | */ 107 | public static SketchStyle createSketchStyle(FeatureTemplate featureTemplate, FeatureLayer featureLayer) { 108 | Graphic graphic = new Graphic(); 109 | graphic.getAttributes().putAll(Objects.requireNonNull(featureTemplate, "featureTemplate").getPrototypeAttributes()); 110 | Symbol symbol = Objects.requireNonNull(featureLayer, "featureLayer").getRenderer().getSymbol(graphic); 111 | 112 | SketchStyle sketchStyle = new SketchStyle(); 113 | 114 | if (symbol instanceof MultilayerSymbol) { 115 | if (symbol instanceof MultilayerPointSymbol) { 116 | sketchStyle.setMultilayerVertexSymbol((MultilayerPointSymbol) symbol); 117 | sketchStyle.setMultilayerFeedbackVertexSymbol(sketchStyle.getMultilayerVertexSymbol()); 118 | sketchStyle.setMultilayerSelectedVertexSymbol(sketchStyle.getMultilayerVertexSymbol()); 119 | } 120 | if (symbol instanceof MultilayerPolylineSymbol) { 121 | sketchStyle.setMultilayerLineSymbol((MultilayerPolylineSymbol) symbol); 122 | sketchStyle.setMultilayerFeedbackLineSymbol(sketchStyle.getMultilayerLineSymbol()); 123 | sketchStyle.setFeedbackVertexSymbol(sketchStyle.getVertexSymbol()); 124 | } 125 | if (symbol instanceof MultilayerPolygonSymbol) { 126 | sketchStyle.setMultilayerFillSymbol((MultilayerPolygonSymbol) symbol); 127 | sketchStyle.setMultilayerFeedbackFillSymbol(sketchStyle.getMultilayerFillSymbol()); 128 | sketchStyle.setFeedbackVertexSymbol(sketchStyle.getVertexSymbol()); 129 | } 130 | } else { 131 | if (symbol instanceof MarkerSymbol) { 132 | sketchStyle.setVertexSymbol((MarkerSymbol) symbol); 133 | sketchStyle.setFeedbackVertexSymbol(sketchStyle.getVertexSymbol()); 134 | sketchStyle.setSelectedVertexSymbol(sketchStyle.getVertexSymbol()); 135 | } 136 | if (symbol instanceof LineSymbol) { 137 | sketchStyle.setLineSymbol((LineSymbol) symbol); 138 | sketchStyle.setFeedbackLineSymbol(sketchStyle.getLineSymbol()); 139 | sketchStyle.setFeedbackVertexSymbol(sketchStyle.getVertexSymbol()); 140 | } 141 | if (symbol instanceof FillSymbol) { 142 | sketchStyle.setFillSymbol((FillSymbol) symbol); 143 | sketchStyle.setFeedbackFillSymbol(sketchStyle.getFillSymbol()); 144 | sketchStyle.setFeedbackVertexSymbol(sketchStyle.getVertexSymbol()); 145 | } 146 | } 147 | 148 | return sketchStyle; 149 | } 150 | } 151 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/UtilityNetworkTraceStartingPoint.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit; 18 | 19 | import com.esri.arcgisruntime.geometry.Envelope; 20 | import com.esri.arcgisruntime.geometry.GeometryEngine; 21 | import com.esri.arcgisruntime.geometry.Polyline; 22 | import com.esri.arcgisruntime.mapping.view.Graphic; 23 | import com.esri.arcgisruntime.symbology.Symbol; 24 | import com.esri.arcgisruntime.utilitynetworks.UtilityElement; 25 | import com.esri.arcgisruntime.utilitynetworks.UtilityNetworkSource; 26 | import javafx.beans.property.SimpleDoubleProperty; 27 | 28 | /** 29 | * A model for a starting point used for running a utility network trace by a {@link UtilityNetworkTraceTool}. 30 | * 31 | * @since 100.15.0 32 | */ 33 | public class UtilityNetworkTraceStartingPoint { 34 | 35 | private final SimpleDoubleProperty fractionAlongEdgeProperty = new SimpleDoubleProperty(); 36 | 37 | private boolean hasMultipleTerminals = false; 38 | private boolean hasFractionAlongEdge = false; 39 | private final Envelope extent; 40 | private final Graphic graphic; 41 | private final Symbol featureSymbol; 42 | private final UtilityElement utilityElement; 43 | 44 | /** 45 | * Creates a UtilityNetworkTraceStartingPoint. 46 | * 47 | * @param utilityElement the utility element the starting point represents 48 | * @param graphic the graphic used to display the starting point location on the MapView 49 | * @param featureSymbol the symbol of the feature itself 50 | * @param extent the extent of the feature used to create the utilityElement 51 | * @since 100.15.0 52 | */ 53 | protected UtilityNetworkTraceStartingPoint( 54 | UtilityElement utilityElement, Graphic graphic, Symbol featureSymbol, Envelope extent) { 55 | this.utilityElement = utilityElement; 56 | this.graphic = graphic; 57 | this.featureSymbol = featureSymbol; 58 | this.extent = extent; 59 | // Determine whether the starting point has multiple terminals. 60 | // Can be used to display terminal picker in UI. 61 | if (utilityElement.getAssetType().getTerminalConfiguration() != null && 62 | utilityElement.getAssetType().getTerminalConfiguration().getTerminals().size() > 1) { 63 | hasMultipleTerminals = true; 64 | } 65 | // determine whether the starting point requires fraction along edge properties 66 | if (utilityElement.getNetworkSource().getSourceType() == UtilityNetworkSource.Type.EDGE && 67 | graphic != null && graphic.getGeometry() instanceof Polyline) { 68 | hasFractionAlongEdge = true; 69 | fractionAlongEdgeProperty.set(utilityElement.getFractionAlongEdge()); 70 | var polyline = (Polyline) graphic.getGeometry(); 71 | graphic.setGeometry( 72 | GeometryEngine.createPointAlong(polyline, GeometryEngine.length(polyline) * fractionAlongEdgeProperty.get())); 73 | // Add a listener to the fraction along edge property to update the geometry of the graphic to reposition 74 | // along the line at the new location, and update the fraction along edge value on the utility element. 75 | fractionAlongEdgeProperty.addListener((observable, oldValue, newValue) -> { 76 | graphic.setGeometry( 77 | GeometryEngine.createPointAlong(polyline, GeometryEngine.length(polyline) * newValue.doubleValue())); 78 | utilityElement.setFractionAlongEdge(newValue.doubleValue()); 79 | }); 80 | } 81 | } 82 | 83 | /** 84 | * Returns the fraction along edge property. 85 | * 86 | * @return the fraction along edge property. Null if the starting point is not an edge feature 87 | * @since 100.15.0 88 | */ 89 | public SimpleDoubleProperty fractionAlongEdgeProperty() { 90 | return fractionAlongEdgeProperty; 91 | } 92 | 93 | /** 94 | * Returns the fraction along edge value. 95 | * 96 | * @return the fraction along edge value. Null if the starting point is not an edge feature 97 | * @since 100.15.0 98 | */ 99 | public Double getFractionAlongEdge() { 100 | return fractionAlongEdgeProperty.get(); 101 | } 102 | 103 | /** 104 | * Sets the fraction along edge value. 105 | * 106 | * @param fractionAlongEdge the fraction along edge value. 107 | * @since 100.15.0 108 | */ 109 | public void setFractionAlongEdge(Double fractionAlongEdge) { 110 | fractionAlongEdgeProperty.set(fractionAlongEdge); 111 | } 112 | 113 | /** 114 | * Returns a boolean value which determines whether the starting point has a fraction along edge. 115 | * 116 | * @return the hasFractionAlongEdge value. True if it does, false otherwise 117 | * @since 100.15.0 118 | */ 119 | public boolean getHasFractionAlongEdge() { 120 | return hasFractionAlongEdge; 121 | } 122 | 123 | /** 124 | * Returns a boolean value which determines whether the starting point has multiple terminals. 125 | * 126 | * @return the hasMultipleTerminals value. True if there is more than 1 terminal, false otherwise 127 | * @since 100.15.0 128 | */ 129 | public boolean getHasMultipleTerminals() { 130 | return hasMultipleTerminals; 131 | } 132 | 133 | /** 134 | * Returns an Envelope of the extent of the feature used to create the UtilityElement this starting point is based on. 135 | * 136 | * @return the extent of the feature 137 | * @since 100.15.0 138 | */ 139 | public Envelope getExtent() { 140 | return extent; 141 | } 142 | 143 | /** 144 | * Returns the graphic associated with the starting point. 145 | * 146 | * @return the graphic 147 | * @since 100.15.0 148 | */ 149 | public Graphic getGraphic() { 150 | return graphic; 151 | } 152 | 153 | /** 154 | * Updates the symbol attached to the starting point's graphic. 155 | * 156 | * @param symbol te symbol to set to the graphic 157 | * @since 100.15.0 158 | */ 159 | public void updateSelectionGraphicSymbol(Symbol symbol) { 160 | graphic.setSymbol(symbol); 161 | } 162 | 163 | /** 164 | * Returns the feature symbol for the starting point. 165 | * 166 | * @return the symbol 167 | * @since 100.15.0 168 | */ 169 | public Symbol getFeatureSymbol() { 170 | return featureSymbol; 171 | } 172 | 173 | /** 174 | * Returns the UtilityElement associated with the starting point. 175 | * 176 | * @return the utility element 177 | * @since 100.15.0 178 | */ 179 | public UtilityElement getUtilityElement() { 180 | return utilityElement; 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/UtilityNetworkTraceToolCompletedTrace.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.esri.arcgisruntime.toolkit; 17 | 18 | import java.util.List; 19 | 20 | import com.esri.arcgisruntime.utilitynetworks.UtilityTraceParameters; 21 | import com.esri.arcgisruntime.utilitynetworks.UtilityTraceResult; 22 | 23 | /** 24 | * A model for a complete trace from a {@link UtilityNetworkTraceTool} that enables access to the results. 25 | * 26 | * @since 100.15.0 27 | */ 28 | public class UtilityNetworkTraceToolCompletedTrace { 29 | 30 | private final List utilityTraceResults; 31 | private final Exception exception; 32 | private final UtilityTraceParameters utilityTraceParameters; 33 | 34 | /** 35 | * Creates a UtilityNetworkTraceToolCompletedTrace. 36 | * 37 | * @param utilityTraceResults the results associated with the trace 38 | * @param exception the exception associated with an unsuccessful result 39 | * @param utilityTraceParameters the utility trace parameters used to run the trace 40 | * @since 100.15.0 41 | */ 42 | protected UtilityNetworkTraceToolCompletedTrace( 43 | List utilityTraceResults, 44 | Exception exception, 45 | UtilityTraceParameters utilityTraceParameters) { 46 | this.utilityTraceResults = utilityTraceResults; 47 | this.exception = exception; 48 | this.utilityTraceParameters = utilityTraceParameters; 49 | } 50 | 51 | /** 52 | * Returns the utility trace results associated with the completed trace. 53 | * 54 | * @return a list of the results 55 | * @since 100.15.0 56 | */ 57 | public List getUtilityTraceResults() { 58 | return utilityTraceResults; 59 | } 60 | 61 | /** 62 | * Returns the exception resulting from a failed trace. 63 | * 64 | * @return the exception. Null if the trace was successful. 65 | * @since 100.15.0 66 | */ 67 | public Exception getException() { 68 | return exception; 69 | } 70 | 71 | /** 72 | * Returns the UtilityTraceParameters used in the trace. 73 | * 74 | * @return the utility trace parameters 75 | * @since 100.15.0 76 | */ 77 | public UtilityTraceParameters getUtilityTraceParameters() { 78 | return utilityTraceParameters; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Toolkit. 19 | */ 20 | package com.esri.arcgisruntime.toolkit; 21 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/skins/AlternatingBarScalebarSkin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.skins; 18 | 19 | import com.esri.arcgisruntime.geometry.LinearUnit; 20 | import com.esri.arcgisruntime.toolkit.Scalebar; 21 | import com.esri.arcgisruntime.toolkit.ScalebarUtil; 22 | import javafx.geometry.Insets; 23 | import javafx.scene.control.Label; 24 | import javafx.scene.effect.DropShadow; 25 | import javafx.scene.layout.Pane; 26 | import javafx.scene.shape.Rectangle; 27 | 28 | /** 29 | * A scalebar skin that displays the distance as an alternating color solid bar with labels on each segment. 30 | * 31 | * @since 100.2.1 32 | */ 33 | public final class AlternatingBarScalebarSkin extends ScalebarSkin { 34 | 35 | private final Pane labelPane = new Pane(); 36 | private final Pane segmentPane = new Pane(); 37 | 38 | /** 39 | * Creates a new skin instance. 40 | * 41 | * @param scalebar the scalebar this skin is for 42 | * @since 100.2.1 43 | */ 44 | public AlternatingBarScalebarSkin(Scalebar scalebar) { 45 | super(scalebar); 46 | 47 | getVBox().getChildren().addAll(segmentPane, labelPane); 48 | } 49 | 50 | @Override 51 | protected void update(double width, double height) { 52 | // workout the scalebar width, the distance it represents and the correct unit label 53 | // workout how much space is available 54 | double availableWidth = calculateAvailableWidth(width); 55 | // workout the maximum distance the scalebar could show 56 | double maxDistance = calculateDistance(getSkinnable().mapViewProperty().get(), getBaseUnit(), availableWidth); 57 | // get a distance that is a nice looking number 58 | double displayDistance = ScalebarUtil.calculateBestScalebarLength(maxDistance, getBaseUnit(), false); 59 | // workout what the bar width is to match the distance we're going to display 60 | double displayWidth = calculateDisplayWidth(displayDistance, maxDistance, availableWidth); 61 | // decide on the actual unit e.g. km or m 62 | LinearUnit displayUnits = ScalebarUtil.selectLinearUnit(displayDistance, getUnitSystem()); 63 | // get the distance to be displayed in that unit 64 | displayDistance = ScalebarUtil.calculateDistanceInDisplayUnits(displayDistance, getBaseUnit(), displayUnits); 65 | 66 | // create a label to use to work out how many labels can fit in the scale bar width 67 | String sampleLabelString = ScalebarUtil.labelString(displayDistance); 68 | // possibly the total distance string is shorter than the other labels if they have decimal parts so 69 | // make sure we use a minimum of 3 characters 70 | if (sampleLabelString.length() < 3) { 71 | sampleLabelString = "9.9"; 72 | } 73 | Label sampleLabel = new Label(sampleLabelString); 74 | // apply some padding so the labels have some space around them 75 | sampleLabel.setPadding(new Insets(0.0, 10.0, 0.0, 10.0)); 76 | 77 | double widthOfLabel = calculateRegion(sampleLabel).getWidth(); 78 | int maximumNumberOfSegments = (int) (displayWidth / widthOfLabel); 79 | 80 | int bestNumberOfSegments = ScalebarUtil.calculateOptimalNumberOfSegments(displayDistance, maximumNumberOfSegments); 81 | 82 | double segmentWidth = displayWidth / bestNumberOfSegments; 83 | double segmentDistance = displayDistance / bestNumberOfSegments; 84 | 85 | // clear out all the labels, segments and dividers 86 | labelPane.getChildren().clear(); 87 | labelPane.setMaxWidth(displayWidth); 88 | 89 | segmentPane.getChildren().clear(); 90 | segmentPane.setMaxWidth(displayWidth); 91 | 92 | Label label; 93 | Rectangle barSegment; 94 | 95 | for (int i = 0; i < bestNumberOfSegments; ++i) { 96 | label = new Label(ScalebarUtil.labelString(i * segmentDistance)); 97 | label.setTextFill(TEXT_COLOR); 98 | 99 | // first label is aligned with its left to the edge of the bar while the intermediate 100 | // labels are centered on the dividers 101 | if (i > 0) { 102 | label.setTranslateX((i * segmentWidth) - (calculateRegion(label).getWidth() / 2.0)); 103 | } 104 | labelPane.getChildren().add(label); 105 | 106 | // create a rectangle for the segment and translate it into the correct position 107 | barSegment = new Rectangle(); 108 | barSegment.setHeight(HEIGHT); 109 | barSegment.setWidth(segmentWidth); 110 | barSegment.setTranslateX(i * segmentWidth); 111 | barSegment.setTranslateY(HEIGHT / 4.0); 112 | barSegment.setStroke(LINE_COLOR); 113 | barSegment.setStrokeWidth(STROKE_WIDTH); 114 | barSegment.setEffect(new DropShadow(1.0, SHADOW_OFFSET, SHADOW_OFFSET, SHADOW_COLOR)); 115 | barSegment.setArcWidth(1.5); 116 | barSegment.setArcHeight(1.5); 117 | if (i % 2 == 0) { 118 | barSegment.setFill(FILL_COLOR); 119 | } else { 120 | barSegment.setFill(ALTERNATE_FILL_COLOR); 121 | } 122 | 123 | segmentPane.getChildren().add(barSegment); 124 | } 125 | 126 | // the last label is aligned so its end is at the end of the line so it is done outside the loop 127 | label = new Label(ScalebarUtil.labelString(displayDistance)); 128 | // translate it into the correct position 129 | label.setTranslateX((bestNumberOfSegments * segmentWidth) - calculateRegion(label).getWidth()); 130 | // then add the units on so the end of the number aligns with the end of the bar and the unit is off the end 131 | label.setText(ScalebarUtil.labelString(displayDistance) + displayUnits.getAbbreviation()); 132 | label.setTextFill(TEXT_COLOR); 133 | labelPane.getChildren().add(label); 134 | 135 | // move the bar and labels into their final position - slightly off center due to the units 136 | Label abbreviationLabel = new Label(displayUnits.getAbbreviation()); 137 | segmentPane.setTranslateX(-calculateRegion(abbreviationLabel).getWidth() / 2.0); 138 | labelPane.setTranslateX(-calculateRegion(abbreviationLabel).getWidth() / 2.0); 139 | 140 | // adjust for left/right/center alignment 141 | getVBox().setTranslateX( 142 | calculateAlignmentTranslationX(width, 143 | displayWidth + calculateRegion(new Label(displayUnits.getAbbreviation())).getWidth())); 144 | 145 | // set invisible if distance is zero 146 | getVBox().setVisible(displayDistance > 0); 147 | } 148 | 149 | @Override 150 | protected double calculateAvailableWidth(double width) { 151 | return width - (calculateRegion(new Label("mm")).getWidth()) - SHADOW_OFFSET; 152 | } 153 | 154 | @Override 155 | protected double computePrefHeight( 156 | double width, double topInset, double rightInset, double bottomInset, double leftInset) { 157 | return topInset + bottomInset + HEIGHT + STROKE_WIDTH + calculateRegion(new Label()).getHeight(); 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/skins/BarScalebarSkin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.skins; 18 | 19 | import com.esri.arcgisruntime.geometry.LinearUnit; 20 | import com.esri.arcgisruntime.toolkit.Scalebar; 21 | import com.esri.arcgisruntime.toolkit.ScalebarUtil; 22 | import javafx.scene.control.Label; 23 | import javafx.scene.effect.DropShadow; 24 | import javafx.scene.shape.Rectangle; 25 | 26 | /** 27 | * A scalebar skin that displays the distance as a solid bar with a single label. 28 | * 29 | * @since 100.2.1 30 | */ 31 | public final class BarScalebarSkin extends ScalebarSkin { 32 | 33 | private final Label distanceLabel = new Label(); 34 | private final Rectangle bar = new Rectangle(); 35 | private final Rectangle outerBar = new Rectangle(); 36 | 37 | /** 38 | * Creates a new skin instance. 39 | * 40 | * @param scalebar the scalebar this skin is for 41 | * @since 100.2.1 42 | */ 43 | public BarScalebarSkin(Scalebar scalebar) { 44 | super(scalebar); 45 | 46 | bar.setFill(FILL_COLOR); 47 | bar.setHeight(HEIGHT); 48 | bar.setStroke(LINE_COLOR); 49 | bar.setStrokeWidth(STROKE_WIDTH); 50 | bar.setEffect(new DropShadow(1.0, SHADOW_OFFSET, SHADOW_OFFSET, SHADOW_COLOR)); 51 | bar.setArcWidth(1.5); 52 | bar.setArcHeight(1.5); 53 | 54 | distanceLabel.setTextFill(TEXT_COLOR); 55 | 56 | getVBox().getChildren().addAll(bar, distanceLabel); 57 | } 58 | 59 | @Override 60 | protected void update(double width, double height) { 61 | // workout the scalebar width, the distance it represents and the correct unit label 62 | // workout how much space is available 63 | double availableWidth = calculateAvailableWidth(width); 64 | // workout the maximum distance the scalebar could show 65 | double maxDistance = calculateDistance(getSkinnable().mapViewProperty().get(), getBaseUnit(), availableWidth); 66 | // get a distance that is a nice looking number 67 | double displayDistance = ScalebarUtil.calculateBestScalebarLength(maxDistance, getBaseUnit(), false); 68 | // workout what the bar width is to match the distance we're going to display 69 | double displayWidth = calculateDisplayWidth(displayDistance, maxDistance, availableWidth); 70 | // decide on the actual unit e.g. km or m 71 | LinearUnit displayUnits = ScalebarUtil.selectLinearUnit(displayDistance, getUnitSystem()); 72 | // get the distance to be displayed in that unit 73 | displayDistance = ScalebarUtil.calculateDistanceInDisplayUnits(displayDistance, getBaseUnit(), displayUnits); 74 | 75 | // update the bar size 76 | bar.setWidth(displayWidth); 77 | outerBar.setWidth(displayWidth); 78 | 79 | // update the label 80 | distanceLabel.setText(ScalebarUtil.labelString(displayDistance) + displayUnits.getAbbreviation()); 81 | 82 | // adjust for left/right/center alignment 83 | getVBox().setTranslateX(calculateAlignmentTranslationX(width, displayWidth)); 84 | 85 | // set invisible if distance is zero 86 | getVBox().setVisible(displayDistance > 0); 87 | } 88 | 89 | @Override 90 | protected double calculateAvailableWidth(double width) { 91 | return width - STROKE_WIDTH - SHADOW_OFFSET; 92 | } 93 | 94 | @Override 95 | protected double computePrefHeight( 96 | double width, double topInset, double rightInset, double bottomInset, double leftInset) { 97 | return topInset + bottomInset + HEIGHT + STROKE_WIDTH + calculateRegion(new Label()).getHeight(); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/skins/CompassSkin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.skins; 18 | 19 | import com.esri.arcgisruntime.toolkit.Compass; 20 | import javafx.animation.FadeTransition; 21 | import javafx.application.Platform; 22 | import javafx.beans.property.SimpleBooleanProperty; 23 | import javafx.beans.property.SimpleDoubleProperty; 24 | import javafx.event.ActionEvent; 25 | import javafx.geometry.HPos; 26 | import javafx.geometry.VPos; 27 | import javafx.scene.control.SkinBase; 28 | import javafx.scene.layout.StackPane; 29 | import javafx.scene.paint.Color; 30 | import javafx.scene.shape.Circle; 31 | import javafx.scene.shape.ClosePath; 32 | import javafx.scene.shape.HLineTo; 33 | import javafx.scene.shape.MoveTo; 34 | import javafx.scene.shape.Path; 35 | import javafx.scene.shape.PathElement; 36 | import javafx.scene.shape.StrokeType; 37 | import javafx.scene.shape.VLineTo; 38 | import javafx.util.Duration; 39 | 40 | import java.util.concurrent.Executors; 41 | import java.util.concurrent.ScheduledExecutorService; 42 | import java.util.concurrent.TimeUnit; 43 | 44 | /** 45 | * Implements a skin for the {@link Compass} control. 46 | * 47 | * @since 100.2.1 48 | */ 49 | public final class CompassSkin extends SkinBase { 50 | 51 | private static final double PREF_SIZE = 100.0; 52 | 53 | // how close to north the compass has to be to auto-hide 54 | private static final double HEADING_TOLERANCE = 0.25; 55 | 56 | private boolean invalid = true; 57 | private final StackPane stackPane = new StackPane(); 58 | 59 | // duration used for fading the compass 60 | private static final long TIMER_DURATION = 500; 61 | 62 | // property that will be true when the compass is hidden 63 | private final SimpleBooleanProperty hiddenProperty = new SimpleBooleanProperty(true); 64 | 65 | // a scheduled service used to perform a delayed fade in/out if auto-hide is enabled 66 | private final ScheduledExecutorService scheduledService = Executors.newScheduledThreadPool(0); 67 | 68 | /** 69 | * Creates an instance of the skin. 70 | * 71 | * @param control the {@link Compass} control this skin represents 72 | * @since 100.2.1 73 | */ 74 | public CompassSkin(com.esri.arcgisruntime.toolkit.Compass control) { 75 | super(control); 76 | 77 | control.widthProperty().addListener(observable -> invalid = true); 78 | control.heightProperty().addListener(observable -> invalid = true); 79 | control.insetsProperty().addListener(observable -> invalid = true); 80 | 81 | // bind to the control's heading property 82 | stackPane.rotateProperty().bind(control.headingProperty().negate()); 83 | 84 | // hide the compass when the heading is close to north if the auto hide property is enabled 85 | SimpleDoubleProperty controlHeadingProperty = control.headingProperty(); 86 | hiddenProperty.bind(control.autoHideProperty() 87 | .and(controlHeadingProperty.isEqualTo(0.0, HEADING_TOLERANCE) 88 | .or(controlHeadingProperty.isEqualTo(360.0, HEADING_TOLERANCE)))); 89 | hiddenProperty.addListener(observable -> { 90 | // when the hidden property changes schedule to perform a fade in/out - having a delay prevents the compass from 91 | // starting to fade if it momentarily passes through north 92 | scheduledService.schedule(() -> Platform.runLater(() -> { 93 | FadeTransition fadeTransition = new FadeTransition(Duration.millis(TIMER_DURATION), stackPane); 94 | if (hiddenProperty.get()) { 95 | fadeTransition.setToValue(0.0); 96 | } else { 97 | fadeTransition.setToValue(1.0); 98 | } 99 | fadeTransition.play(); 100 | }), TIMER_DURATION, TimeUnit.MILLISECONDS); 101 | }); 102 | 103 | // initial opacity based on the auto-hide property 104 | if (control.isAutoHide()) { 105 | stackPane.setOpacity(0.0); 106 | } else { 107 | stackPane.setOpacity(1.0); 108 | } 109 | 110 | getChildren().add(stackPane); 111 | } 112 | 113 | @Override 114 | protected void layoutChildren(double contentX, double contentY, double contentWidth, double contentHeight) { 115 | if (invalid) { 116 | update(contentWidth, contentHeight); 117 | invalid = false; 118 | } 119 | layoutInArea(stackPane, contentX, contentY, contentWidth, contentHeight, -1, HPos.CENTER, VPos.CENTER); 120 | } 121 | 122 | /** 123 | * Updates the visual representation of the compass e.g. when the size is changed. 124 | * 125 | * @param width the width of the control 126 | * @param height the height of the control 127 | * @since 100.2.1 128 | */ 129 | private void update(double width, double height) { 130 | stackPane.getChildren().clear(); 131 | 132 | double radius = Math.min(height, width) / 2.0; 133 | double triangleHeight = radius * (3.0 / 5.0); 134 | double triangleWidth = triangleHeight / 3.0; 135 | 136 | PathElement northEastTrianglePath[] = 137 | {new MoveTo(0.0, 0.0), new VLineTo(triangleHeight), new HLineTo(triangleWidth), new ClosePath()}; 138 | PathElement northWestTrianglePath[] = 139 | {new MoveTo(0.0, 0.0), new VLineTo(triangleHeight), new HLineTo(-triangleWidth), new ClosePath()}; 140 | 141 | Path northEastTriangle = new Path(northEastTrianglePath); 142 | northEastTriangle.setStroke(null); 143 | northEastTriangle.setFill(Color.rgb(0x88, 0x00, 0x00)); 144 | northEastTriangle.setTranslateY(-triangleHeight / 2.0); 145 | northEastTriangle.setTranslateX(triangleWidth / 2.0); 146 | 147 | Path southWestTriangle = new Path(northEastTrianglePath); 148 | southWestTriangle.setStroke(null); 149 | southWestTriangle.setFill(Color.rgb(0xA9, 0xA9, 0xA9)); 150 | southWestTriangle.setTranslateY(triangleHeight / 2.0); 151 | southWestTriangle.setTranslateX(-triangleWidth / 2.0); 152 | southWestTriangle.setRotate(180.0); 153 | 154 | Path northWestTriangle = new Path(northWestTrianglePath); 155 | northWestTriangle.setStroke(null); 156 | northWestTriangle.setFill(Color.rgb(0xFF, 0x00, 0x00)); 157 | northWestTriangle.setTranslateY(-triangleHeight / 2.0); 158 | northWestTriangle.setTranslateX(-triangleWidth / 2.0); 159 | 160 | Path southEastTriangle = new Path(northWestTrianglePath); 161 | southEastTriangle.setStroke(null); 162 | southEastTriangle.setFill(Color.rgb(0x80, 0x80, 0x80)); 163 | southEastTriangle.setTranslateY(triangleHeight / 2.0); 164 | southEastTriangle.setTranslateX(triangleWidth / 2.0); 165 | southEastTriangle.setRotate(180.0); 166 | 167 | Circle pivot = new Circle(); 168 | pivot.setRadius(triangleWidth / 3.0); 169 | pivot.setFill(Color.rgb(0xFF, 0xA5, 0x00)); 170 | 171 | Circle circle = new Circle(); 172 | circle.setRadius(radius); 173 | circle.setFill(Color.rgb(0xE1, 0xF1, 0xF5, 0.25)); 174 | circle.setStroke(Color.rgb(0x80, 0x80, 0x80)); 175 | circle.setStrokeType(StrokeType.INSIDE); 176 | circle.setStrokeWidth(0.1 * radius); 177 | 178 | stackPane.getChildren().addAll(circle, northEastTriangle, northWestTriangle, 179 | southEastTriangle, southWestTriangle, pivot); 180 | 181 | // fire action event if any of the compass elements are clicked 182 | stackPane.getChildren().forEach(c -> c.setOnMouseClicked(e -> getSkinnable().fireEvent(new ActionEvent()))); 183 | } 184 | 185 | @Override 186 | protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double 187 | leftInset) { 188 | return computePrefWidth(height, topInset, rightInset, bottomInset, leftInset); 189 | } 190 | 191 | @Override 192 | protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double 193 | leftInset) { 194 | return computePrefHeight(width, topInset, rightInset, bottomInset, leftInset); 195 | } 196 | 197 | @Override 198 | protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double 199 | leftInset) { 200 | return computePrefWidth(height, topInset, rightInset, bottomInset, leftInset); 201 | } 202 | 203 | @Override 204 | protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double 205 | leftInset) { 206 | return computePrefHeight(width, topInset, rightInset, bottomInset, leftInset); 207 | } 208 | 209 | @Override 210 | protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double 211 | leftInset) { 212 | return PREF_SIZE; 213 | } 214 | 215 | @Override 216 | protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double 217 | leftInset) { 218 | return PREF_SIZE; 219 | } 220 | } 221 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/skins/DualUnitScalebarSkin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.skins; 18 | 19 | import com.esri.arcgisruntime.UnitSystem; 20 | import com.esri.arcgisruntime.geometry.LinearUnit; 21 | import com.esri.arcgisruntime.geometry.LinearUnitId; 22 | import com.esri.arcgisruntime.toolkit.Scalebar; 23 | import com.esri.arcgisruntime.toolkit.ScalebarUtil; 24 | import javafx.scene.control.Label; 25 | import javafx.scene.effect.DropShadow; 26 | import javafx.scene.layout.Pane; 27 | import javafx.scene.shape.LineTo; 28 | import javafx.scene.shape.MoveTo; 29 | import javafx.scene.shape.Path; 30 | import javafx.scene.shape.StrokeLineCap; 31 | 32 | /** 33 | * A scalebar skin that displays the distance in both metric and imperial units. The line is the same as 34 | * {@link LineScaleBarSkin} with the addition of an extra mark on the bottom for the alternate measurement. 35 | * 36 | * @since 100.2.1 37 | */ 38 | public final class DualUnitScalebarSkin extends ScalebarSkin { 39 | 40 | private final Pane primaryLabelPane = new Pane(); 41 | private final Pane secondaryLabelPane = new Pane(); 42 | private final Path line = new Path(); 43 | 44 | private static final LinearUnit METERS = new LinearUnit(LinearUnitId.METERS); 45 | private static final LinearUnit FEET = new LinearUnit(LinearUnitId.FEET); 46 | 47 | /** 48 | * Creates a new skin instance. 49 | * 50 | * @param scalebar the scalebar this skin is for 51 | * @since 100.2.1 52 | */ 53 | public DualUnitScalebarSkin(Scalebar scalebar) { 54 | super(scalebar); 55 | 56 | line.setStroke(LINE_COLOR); 57 | line.setStrokeWidth(STROKE_WIDTH); 58 | line.setStrokeLineCap(StrokeLineCap.ROUND); 59 | line.setEffect(new DropShadow(1.0, SHADOW_OFFSET, SHADOW_OFFSET, SHADOW_COLOR)); 60 | 61 | getVBox().getChildren().addAll(primaryLabelPane, line, secondaryLabelPane); 62 | } 63 | 64 | @Override 65 | protected void update(double width, double height) { 66 | // workout the scalebar width, the distance it represents and the correct unit label 67 | // workout how much space is available 68 | double availableWidth = calculateAvailableWidth(width); 69 | // workout the maximum distance the scalebar could show 70 | double maxDistance = calculateDistance(getSkinnable().mapViewProperty().get(), getBaseUnit(), availableWidth); 71 | // get a distance that is a nice looking number 72 | double displayDistance = ScalebarUtil.calculateBestScalebarLength(maxDistance, getBaseUnit(), false); 73 | // workout what the bar width is to match the distance we're going to display 74 | double displayWidth = calculateDisplayWidth(displayDistance, maxDistance, availableWidth); 75 | // decide on the actual unit e.g. km or m 76 | LinearUnit displayUnits = ScalebarUtil.selectLinearUnit(displayDistance, getUnitSystem()); 77 | // get the distance to be displayed in that unit 78 | displayDistance = ScalebarUtil.calculateDistanceInDisplayUnits(displayDistance, getBaseUnit(), displayUnits); 79 | 80 | // do the same calculations for the secondary units which will be on the bottom of the line 81 | UnitSystem secondaryUnitSystem = getUnitSystem() == UnitSystem.METRIC ? UnitSystem.IMPERIAL : UnitSystem.METRIC; 82 | LinearUnit secondaryBaseUnit = secondaryUnitSystem == UnitSystem.METRIC ? METERS : FEET; 83 | double secondaryMaxDistance = calculateDistance(getSkinnable().mapViewProperty().get(), secondaryBaseUnit, availableWidth); 84 | 85 | double secondaryDisplayDistance = ScalebarUtil.calculateBestScalebarLength(secondaryMaxDistance, secondaryBaseUnit, false); 86 | double secondaryDisplayWidth = calculateDisplayWidth(secondaryDisplayDistance, secondaryMaxDistance, availableWidth); 87 | LinearUnit secondaryDisplayUnits = ScalebarUtil.selectLinearUnit(secondaryDisplayDistance, secondaryUnitSystem); 88 | secondaryDisplayDistance = ScalebarUtil.calculateDistanceInDisplayUnits(secondaryDisplayDistance, secondaryBaseUnit, secondaryDisplayUnits); 89 | 90 | // the line width is the longest of the two display widths 91 | double lineWidth = Math.max(displayWidth, secondaryDisplayWidth); 92 | 93 | primaryLabelPane.getChildren().clear(); 94 | primaryLabelPane.setMaxWidth(lineWidth); 95 | secondaryLabelPane.getChildren().clear(); 96 | secondaryLabelPane.setMaxWidth(lineWidth); 97 | 98 | // update the line 99 | line.getElements().clear(); 100 | line.getElements().addAll( 101 | new MoveTo(0.0, HEIGHT * 2.0), 102 | new LineTo(0.0, 0.0), 103 | new MoveTo(0.0, HEIGHT), 104 | new LineTo(lineWidth, HEIGHT), 105 | new MoveTo(displayWidth, HEIGHT), 106 | new LineTo(displayWidth, 0.0), 107 | new MoveTo(secondaryDisplayWidth, HEIGHT * 2.0), 108 | new LineTo(secondaryDisplayWidth, HEIGHT)); 109 | 110 | // label the ticks 111 | // the last label is aligned so its end is at the end of the line so it is done outside the loop 112 | Label primaryLabel = new Label(ScalebarUtil.labelString(displayDistance)); 113 | // translate it into the correct position 114 | primaryLabel.setTranslateX(displayWidth - calculateRegion(primaryLabel).getWidth()); 115 | // then add the units on so the end of the number aligns with the end of the bar and the unit is off the end 116 | primaryLabel.setText(ScalebarUtil.labelString(displayDistance) + displayUnits.getAbbreviation()); 117 | primaryLabel.setTextFill(TEXT_COLOR); 118 | primaryLabelPane.getChildren().add(primaryLabel); 119 | 120 | Label secondaryLabel = new Label(ScalebarUtil.labelString(secondaryDisplayDistance)); 121 | secondaryLabel.setTranslateX(secondaryDisplayWidth - calculateRegion(secondaryLabel).getWidth()); 122 | // then add the units on so the end of the number aligns with the end of the bar and the unit is off the end 123 | secondaryLabel.setText(ScalebarUtil.labelString(secondaryDisplayDistance) + secondaryDisplayUnits.getAbbreviation()); 124 | secondaryLabel.setTextFill(TEXT_COLOR); 125 | secondaryLabelPane.getChildren().add(secondaryLabel); 126 | 127 | // the unit label that will be at the end of the line 128 | Label endUnits = new Label(displayWidth >= secondaryDisplayWidth ? displayUnits.getAbbreviation() : secondaryDisplayUnits.getAbbreviation()); 129 | 130 | // move the line and labels into their final position - slightly off center due to the units 131 | line.setTranslateX(-calculateRegion(endUnits).getWidth() / 2.0); 132 | primaryLabelPane.setTranslateX(-calculateRegion(new Label(displayUnits.getAbbreviation())).getWidth() / 2.0); 133 | secondaryLabelPane.setTranslateX(-calculateRegion(new Label(secondaryDisplayUnits.getAbbreviation())).getWidth() / 2.0); 134 | 135 | // adjust for left/right/center alignment 136 | getVBox().setTranslateX(calculateAlignmentTranslationX(width, lineWidth + calculateRegion(endUnits).getWidth())); 137 | 138 | // set invisible if distance is zero 139 | getVBox().setVisible(displayDistance > 0); 140 | } 141 | 142 | @Override 143 | protected double calculateAvailableWidth(double width) { 144 | return width - (calculateRegion(new Label("mm")).getWidth()) - STROKE_WIDTH - SHADOW_OFFSET; 145 | } 146 | 147 | @Override 148 | protected double computePrefHeight( 149 | double width, double topInset, double rightInset, double bottomInset, double leftInset) { 150 | return topInset + bottomInset + (HEIGHT * 2.0) + STROKE_WIDTH + (calculateRegion(new Label()).getHeight() * 2.0); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/skins/GraduatedLineScalebarSkin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.skins; 18 | 19 | import com.esri.arcgisruntime.geometry.LinearUnit; 20 | import com.esri.arcgisruntime.toolkit.Scalebar; 21 | import com.esri.arcgisruntime.toolkit.ScalebarUtil; 22 | import javafx.geometry.Insets; 23 | import javafx.scene.control.Label; 24 | import javafx.scene.effect.DropShadow; 25 | import javafx.scene.layout.Pane; 26 | import javafx.scene.shape.LineTo; 27 | import javafx.scene.shape.MoveTo; 28 | import javafx.scene.shape.Path; 29 | import javafx.scene.shape.StrokeLineCap; 30 | 31 | /** 32 | * A scalebar skin that displays the distance as a line with vertical marks and labels evenly spaced along the line. 33 | * 34 | * @since 100.2.1 35 | */ 36 | public final class GraduatedLineScalebarSkin extends ScalebarSkin { 37 | 38 | private final static double TICK_HEIGHT = 0.75 * HEIGHT; 39 | 40 | private final Pane labelPane = new Pane(); 41 | private final Path line = new Path(); 42 | 43 | /** 44 | * Creates a new skin instance. 45 | * 46 | * @param scalebar the scalebar this skin is for 47 | * @since 100.2.1 48 | */ 49 | public GraduatedLineScalebarSkin(Scalebar scalebar) { 50 | super(scalebar); 51 | 52 | line.setStroke(LINE_COLOR); 53 | line.setStrokeWidth(STROKE_WIDTH); 54 | line.setStrokeLineCap(StrokeLineCap.ROUND); 55 | line.setEffect(new DropShadow(1.0, SHADOW_OFFSET, SHADOW_OFFSET, SHADOW_COLOR)); 56 | 57 | getVBox().getChildren().addAll(line, labelPane); 58 | } 59 | 60 | @Override 61 | protected void update(double width, double height) { 62 | // workout the scalebar width, the distance it represents and the correct unit label 63 | // workout how much space is available 64 | double availableWidth = calculateAvailableWidth(width); 65 | // workout the maximum distance the scalebar could show 66 | double maxDistance = calculateDistance(getSkinnable().mapViewProperty().get(), getBaseUnit(), availableWidth); 67 | // get a distance that is a nice looking number 68 | double displayDistance = ScalebarUtil.calculateBestScalebarLength(maxDistance, getBaseUnit(), false); 69 | // workout what the bar width is to match the distance we're going to display 70 | double displayWidth = calculateDisplayWidth(displayDistance, maxDistance, availableWidth); 71 | // decide on the actual unit e.g. km or m 72 | LinearUnit displayUnits = ScalebarUtil.selectLinearUnit(displayDistance, getUnitSystem()); 73 | // get the distance to be displayed in that unit 74 | displayDistance = ScalebarUtil.calculateDistanceInDisplayUnits(displayDistance, getBaseUnit(), displayUnits); 75 | 76 | // create a label to use to work out how many labels can fit in the scale bar width 77 | String sampleLabelString = ScalebarUtil.labelString(displayDistance); 78 | // possibly the total distance string is shorter than the other labels if they have decimal parts so 79 | // make sure we use a minimum of 3 characters 80 | if (sampleLabelString.length() < 3) { 81 | sampleLabelString = "9.9"; 82 | } 83 | Label sampleLabel = new Label(sampleLabelString); 84 | sampleLabel.setPadding(new Insets(0.0, 10.0, 0.0, 10.0)); 85 | 86 | double widthOfLabel = calculateRegion(sampleLabel).getWidth(); 87 | int maximumNumberOfSegments = (int) (displayWidth / widthOfLabel); 88 | 89 | int bestNumberOfSegments = ScalebarUtil.calculateOptimalNumberOfSegments(displayDistance, maximumNumberOfSegments); 90 | 91 | double segmentWidth = displayWidth / bestNumberOfSegments; 92 | double segmentDistance = displayDistance / bestNumberOfSegments; 93 | 94 | labelPane.getChildren().clear(); 95 | labelPane.setMaxWidth(displayWidth); 96 | 97 | // update the line and labels 98 | line.getElements().clear(); 99 | line.getElements().addAll(new MoveTo(0.0, 0.0), new LineTo(0.0, HEIGHT)); 100 | 101 | Label label; 102 | 103 | for (int i = 0; i < bestNumberOfSegments; ++i) { 104 | label = new Label(ScalebarUtil.labelString(i * segmentDistance)); 105 | label.setTextFill(TEXT_COLOR); 106 | // first label is aligned with its left to the edge of the bar while the intermediate 107 | // labels are centered on the ticks 108 | if (i > 0) { 109 | label.setTranslateX((i * segmentWidth) - (calculateRegion(label).getWidth() / 2.0)); 110 | } 111 | labelPane.getChildren().add(label); 112 | 113 | line.getElements().addAll( 114 | new LineTo(i * segmentWidth, HEIGHT), 115 | new LineTo(i * segmentWidth, HEIGHT - TICK_HEIGHT), 116 | new MoveTo(i * segmentWidth, HEIGHT)); 117 | } 118 | // the last label is aligned so its end is at the end of the line so it is done outside the loop 119 | label = new Label(ScalebarUtil.labelString(displayDistance)); 120 | // translate it into the correct position 121 | label.setTranslateX((bestNumberOfSegments * segmentWidth) - calculateRegion(label).getWidth()); 122 | // then add the units on so the end of the number aligns with the end of the bar and the unit is off the end 123 | label.setText(ScalebarUtil.labelString(displayDistance) + displayUnits.getAbbreviation()); 124 | label.setTextFill(TEXT_COLOR); 125 | labelPane.getChildren().add(label); 126 | 127 | // the last part of the line 128 | line.getElements().addAll(new LineTo(displayWidth, HEIGHT), new LineTo(displayWidth, 0.0)); 129 | 130 | // move the line and labels into their final position - slightly off center due to the units 131 | line.setTranslateX(-calculateRegion(new Label(displayUnits.getAbbreviation())).getWidth() / 2.0); 132 | labelPane.setTranslateX(-calculateRegion(new Label(displayUnits.getAbbreviation())).getWidth() / 2.0); 133 | 134 | // adjust for left/right/center alignment 135 | getVBox().setTranslateX(calculateAlignmentTranslationX(width, 136 | displayWidth + calculateRegion(new Label(displayUnits.getAbbreviation())).getWidth())); 137 | 138 | // set invisible if distance is zero 139 | getVBox().setVisible(displayDistance > 0); 140 | } 141 | 142 | @Override 143 | protected double calculateAvailableWidth(double width) { 144 | return width - (calculateRegion(new Label("mm")).getWidth()) - STROKE_WIDTH - SHADOW_OFFSET; 145 | } 146 | 147 | @Override 148 | protected double computePrefHeight( 149 | double width, double topInset, double rightInset, double bottomInset, double leftInset) { 150 | return topInset + bottomInset + HEIGHT + STROKE_WIDTH + calculateRegion(new Label()).getHeight(); 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/skins/LineScaleBarSkin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.skins; 18 | 19 | import com.esri.arcgisruntime.geometry.LinearUnit; 20 | import com.esri.arcgisruntime.toolkit.Scalebar; 21 | import com.esri.arcgisruntime.toolkit.ScalebarUtil; 22 | import javafx.scene.control.Label; 23 | import javafx.scene.effect.DropShadow; 24 | import javafx.scene.shape.LineTo; 25 | import javafx.scene.shape.MoveTo; 26 | import javafx.scene.shape.Path; 27 | import javafx.scene.shape.StrokeLineCap; 28 | 29 | /** 30 | * A scalebar skin that displays the distance as a line with vertical marks at the start and end and a single distance 31 | * label. 32 | * 33 | * @since 100.2.1 34 | */ 35 | public final class LineScaleBarSkin extends ScalebarSkin { 36 | 37 | private final Label distanceLabel = new Label(); 38 | private final Path line = new Path(); 39 | 40 | /** 41 | * Creates a new skin instance. 42 | * 43 | * @param scalebar the scalebar this skin is for 44 | * @since 100.2.1 45 | */ 46 | public LineScaleBarSkin(Scalebar scalebar) { 47 | super(scalebar); 48 | 49 | line.setStroke(LINE_COLOR); 50 | line.setStrokeWidth(STROKE_WIDTH); 51 | line.setStrokeLineCap(StrokeLineCap.ROUND); 52 | line.setEffect(new DropShadow(1.0, SHADOW_OFFSET, SHADOW_OFFSET, SHADOW_COLOR)); 53 | 54 | distanceLabel.setTextFill(TEXT_COLOR); 55 | 56 | getVBox().getChildren().addAll(line, distanceLabel); 57 | } 58 | 59 | @Override 60 | protected void update(double width, double height) { 61 | // workout the scalebar width, the distance it represents and the correct unit label 62 | // workout how much space is available 63 | double availableWidth = calculateAvailableWidth(width); 64 | // workout the maximum distance the scalebar could show 65 | double maxDistance = calculateDistance(getSkinnable().mapViewProperty().get(), getBaseUnit(), availableWidth); 66 | // get a distance that is a nice looking number 67 | double displayDistance = ScalebarUtil.calculateBestScalebarLength(maxDistance, getBaseUnit(), false); 68 | // workout what the bar width is to match the distance we're going to display 69 | double displayWidth = calculateDisplayWidth(displayDistance, maxDistance, availableWidth); 70 | // decide on the actual unit e.g. km or m 71 | LinearUnit displayUnits = ScalebarUtil.selectLinearUnit(displayDistance, getUnitSystem()); 72 | // get the distance to be displayed in that unit 73 | displayDistance = ScalebarUtil.calculateDistanceInDisplayUnits(displayDistance, getBaseUnit(), displayUnits); 74 | 75 | // update the line 76 | line.getElements().clear(); 77 | line.getElements().addAll( 78 | new MoveTo(0.0, HEIGHT), 79 | new LineTo(0.0, 0.0), 80 | new MoveTo(0.0, HEIGHT), 81 | new LineTo(displayWidth, HEIGHT), 82 | new LineTo(displayWidth, 0.0)); 83 | 84 | // update the label 85 | distanceLabel.setText(ScalebarUtil.labelString(displayDistance) + displayUnits.getAbbreviation()); 86 | 87 | // adjust for left/right/center alignment 88 | getVBox().setTranslateX(calculateAlignmentTranslationX(width, displayWidth)); 89 | 90 | // set invisible if distance is zero 91 | getVBox().setVisible(displayDistance > 0); 92 | } 93 | 94 | @Override 95 | protected double calculateAvailableWidth(double width) { 96 | return width - STROKE_WIDTH - SHADOW_OFFSET; 97 | } 98 | 99 | @Override 100 | protected double computePrefHeight( 101 | double width, double topInset, double rightInset, double bottomInset, double leftInset) { 102 | return topInset + bottomInset + HEIGHT + STROKE_WIDTH + calculateRegion(new Label()).getHeight(); 103 | } 104 | } 105 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/skins/OverviewMapSkin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.skins; 18 | 19 | import com.esri.arcgisruntime.geometry.Point; 20 | import com.esri.arcgisruntime.mapping.ArcGISMap; 21 | import com.esri.arcgisruntime.mapping.Viewpoint; 22 | import com.esri.arcgisruntime.mapping.view.GeoView; 23 | import com.esri.arcgisruntime.mapping.view.Graphic; 24 | import com.esri.arcgisruntime.mapping.view.GraphicsOverlay; 25 | import com.esri.arcgisruntime.mapping.view.InteractionListener; 26 | import com.esri.arcgisruntime.mapping.view.MapView; 27 | import com.esri.arcgisruntime.toolkit.OverviewMap; 28 | import javafx.beans.property.SimpleDoubleProperty; 29 | import javafx.scene.control.SkinBase; 30 | import javafx.scene.layout.StackPane; 31 | 32 | /** 33 | * Implements a skin for the {@link OverviewMap} control. 34 | * 35 | * @since 100.2.1 36 | */ 37 | public class OverviewMapSkin extends SkinBase { 38 | 39 | private static final double PREF_WIDTH = 200.0; 40 | private static final double PREF_HEIGHT = 132.0; 41 | 42 | private final GeoView controlGeoView; 43 | private final MapView overviewMapView; 44 | private final Graphic indicatorGraphic = new Graphic(); 45 | private final SimpleDoubleProperty scaleFactorProperty = new SimpleDoubleProperty(); 46 | 47 | /** 48 | * Creates an instance of the skin. 49 | * 50 | * @param control the {@link OverviewMap} control this skin represents 51 | * @since 100.2.1 52 | */ 53 | public OverviewMapSkin(OverviewMap control) { 54 | super(control); 55 | 56 | // create a stack pane holding a map view 57 | overviewMapView = new MapView(); 58 | ArcGISMap map = new ArcGISMap(control.basemapProperty().get()); 59 | overviewMapView.setMap(map); 60 | StackPane stackPane = new StackPane(); 61 | stackPane.getChildren().add(overviewMapView); 62 | getChildren().add(stackPane); 63 | 64 | // add the indicator graphic to the map view 65 | indicatorGraphic.setSymbol(control.symbolProperty().get()); 66 | GraphicsOverlay indicatorOverlay = new GraphicsOverlay(); 67 | indicatorOverlay.getGraphics().add(indicatorGraphic); 68 | overviewMapView.getGraphicsOverlays().add(indicatorOverlay); 69 | 70 | // disable map view interaction 71 | overviewMapView.setInteractionListener(new InteractionListener() {}); 72 | 73 | // hide the attribution 74 | overviewMapView.setAttributionTextVisible(false); 75 | 76 | // add a listener for changes in the GeoView's viewpoint so we can update the overview 77 | controlGeoView = control.geoViewProperty().get(); 78 | controlGeoView.addViewpointChangedListener(v -> update()); 79 | 80 | // listen for changes to the scale factor so that we can update the overview 81 | scaleFactorProperty.bind(control.scaleFactorProperty()); 82 | scaleFactorProperty.addListener(o -> update()); 83 | 84 | // listen for property changes 85 | control.basemapProperty().addListener((observable, oldValue, newValue) -> overviewMapView.getMap().setBasemap(newValue)); 86 | control.symbolProperty().addListener((observable, oldValue, newValue) -> indicatorGraphic.setSymbol(newValue)); 87 | 88 | // make sure the overview starts out up to date 89 | update(); 90 | } 91 | 92 | @Override 93 | protected double computeMinWidth(double height, double topInset, double rightInset, double bottomInset, double 94 | leftInset) { 95 | return computePrefWidth(height, topInset, rightInset, bottomInset, leftInset); 96 | } 97 | 98 | @Override 99 | protected double computeMinHeight(double width, double topInset, double rightInset, double bottomInset, double 100 | leftInset) { 101 | return computePrefHeight(width, topInset, rightInset, bottomInset, leftInset); 102 | } 103 | 104 | @Override 105 | protected double computeMaxWidth(double height, double topInset, double rightInset, double bottomInset, double 106 | leftInset) { 107 | return computePrefWidth(height, topInset, rightInset, bottomInset, leftInset); 108 | } 109 | 110 | @Override 111 | protected double computeMaxHeight(double width, double topInset, double rightInset, double bottomInset, double 112 | leftInset) { 113 | return computePrefHeight(width, topInset, rightInset, bottomInset, leftInset); 114 | } 115 | 116 | @Override 117 | protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double 118 | leftInset) { 119 | return PREF_WIDTH; 120 | } 121 | 122 | @Override 123 | protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double 124 | leftInset) { 125 | return PREF_HEIGHT; 126 | } 127 | 128 | @Override 129 | public void dispose() { 130 | if (overviewMapView != null) { 131 | overviewMapView.dispose(); 132 | } 133 | } 134 | 135 | /** 136 | * Updates the overview when the GeoView's viewpoint changes. 137 | * 138 | * @since 100.14.0 139 | */ 140 | private void update() { 141 | var viewpoint = controlGeoView.getCurrentViewpoint(Viewpoint.Type.CENTER_AND_SCALE); 142 | if (viewpoint != null) { 143 | var scale = viewpoint.getTargetScale() * scaleFactorProperty.get(); 144 | var center = (Point) viewpoint.getTargetGeometry(); 145 | 146 | // keep overview centered on the view's center 147 | overviewMapView.setViewpoint(new Viewpoint(center, scale)); 148 | 149 | // update the graphic that indicates the visible area/center 150 | if (controlGeoView instanceof MapView) { 151 | indicatorGraphic.setGeometry(((MapView) controlGeoView).getVisibleArea()); 152 | } else { 153 | indicatorGraphic.setGeometry(center); 154 | } 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/skins/UtilityNetworkTraceStartingPointView.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.esri.arcgisruntime.toolkit.skins; 17 | 18 | import java.util.concurrent.TimeUnit; 19 | 20 | import com.esri.arcgisruntime.mapping.Viewpoint; 21 | import com.esri.arcgisruntime.toolkit.UtilityNetworkTraceStartingPoint; 22 | import com.esri.arcgisruntime.utilitynetworks.UtilityTerminal; 23 | import javafx.beans.binding.Bindings; 24 | import javafx.geometry.Insets; 25 | import javafx.geometry.Pos; 26 | import javafx.scene.control.Button; 27 | import javafx.scene.control.ComboBox; 28 | import javafx.scene.control.Label; 29 | import javafx.scene.control.Slider; 30 | import javafx.scene.image.ImageView; 31 | import javafx.scene.layout.BorderPane; 32 | import javafx.scene.layout.HBox; 33 | import javafx.scene.layout.Priority; 34 | import javafx.scene.layout.Region; 35 | import javafx.scene.layout.VBox; 36 | import javafx.scene.paint.Color; 37 | import javafx.util.StringConverter; 38 | 39 | /** 40 | * A custom BorderPane for a starting point displayed in a {@link UtilityNetworkTraceSkin}. 41 | * 42 | *

43 | * Has custom style class applied if required for customization: 44 | * utility-network-trace-starting-point-view 45 | * 46 | * @since 100.15.0 47 | */ 48 | public class UtilityNetworkTraceStartingPointView extends BorderPane { 49 | 50 | /** 51 | * Creates a UtilityNetworkTraceStartingPointView. 52 | * 53 | * @param skin the UtilityNetworkTraceSkin skin where the starting point is displayed 54 | * @param startingPoint the UtilityNetworkTraceStartingPoint model for the starting point 55 | * @since 100.15.0 56 | */ 57 | protected UtilityNetworkTraceStartingPointView( 58 | UtilityNetworkTraceSkin skin, UtilityNetworkTraceStartingPoint startingPoint) { 59 | double height = skin.getStartingPointListCellHeight() - 10; 60 | setPrefHeight(height); 61 | setMinHeight(height); 62 | setMaxHeight(height + 15); 63 | setPadding(new Insets(5, 2, 5, 2)); 64 | getStyleClass().add("utility-network-trace-starting-point-view"); 65 | 66 | // Left of the borderpane is a thumbnail image of the feature symbol. 67 | // Setup and configure the feature symbol image 68 | var symbolVBox = new VBox(); 69 | symbolVBox.setAlignment(Pos.CENTER); 70 | symbolVBox.setMinWidth(40); 71 | var featureSymbolImageView = new ImageView(); 72 | symbolVBox.getChildren().add(featureSymbolImageView); 73 | try { 74 | featureSymbolImageView.setImage( 75 | startingPoint.getFeatureSymbol().createSwatchAsync(Color.TRANSPARENT, 1f).get(5, TimeUnit.SECONDS)); 76 | } catch (Exception ex) { 77 | // if the async swatch method fails, set the image to null 78 | featureSymbolImageView.setImage(null); 79 | } 80 | setLeft(symbolVBox); 81 | 82 | // Center of the borderpane are labels denoting the network source and asset group. 83 | // Configure the labels 84 | var networkSourceLabel = new Label(startingPoint.getUtilityElement().getNetworkSource().getName()); 85 | var assetGroupLabel = new Label(startingPoint.getUtilityElement().getAssetGroup().getName()); 86 | var labelsVBox = new VBox(5); 87 | labelsVBox.setAlignment(Pos.CENTER_LEFT); 88 | labelsVBox.getChildren().addAll(networkSourceLabel, assetGroupLabel); 89 | setCenter(labelsVBox); 90 | 91 | // Right of the borderpane are buttons enabling zoom and deletion of the starting point. 92 | // Configure the buttons 93 | var buttonsHBox = new HBox(5); 94 | buttonsHBox.setAlignment(Pos.CENTER); 95 | var zoomButton = new Button(); 96 | Region zoomIcon = new Region(); 97 | zoomIcon.getStyleClass().add("arcgis-toolkit-java-zoom-icon"); 98 | zoomButton.setGraphic(zoomIcon); 99 | if (startingPoint.getExtent() != null) { 100 | zoomButton.setOnAction(e -> skin.controlMapView.setViewpoint(new Viewpoint(startingPoint.getExtent()))); 101 | } else { 102 | zoomButton.setVisible(false); 103 | } 104 | var deleteButton = new Button(); 105 | Region trashIcon = new Region(); 106 | trashIcon.getStyleClass().add("arcgis-toolkit-java-trash-icon"); 107 | deleteButton.setGraphic(trashIcon); 108 | deleteButton.setAlignment(Pos.CENTER_RIGHT); 109 | deleteButton.setOnAction(e -> skin.startingPointsProperty.remove(startingPoint)); 110 | buttonsHBox.getChildren().addAll(zoomButton, deleteButton); 111 | setRight(buttonsHBox); 112 | 113 | // Bottom of the borderpane is optional depending on whether the starting point has a fraction along edge value 114 | // and/or multiple terminals. 115 | // Display a fraction slider if there is a fraction along edge property on the starting point 116 | var fractionSliderVisible = startingPoint.getHasFractionAlongEdge(); 117 | var terminalPickerVisible = startingPoint.getHasMultipleTerminals(); 118 | 119 | if (fractionSliderVisible || terminalPickerVisible) { 120 | var fractionTerminalsVBox = new VBox(5); 121 | setBottom(fractionTerminalsVBox); 122 | 123 | if (fractionSliderVisible) { 124 | var fractionHBox = new HBox(5); 125 | fractionHBox.setMaxWidth(Double.MAX_VALUE); 126 | // configure a slider that adjusts the fraction along edge property 127 | var fractionSlider = new Slider(); 128 | fractionSlider.setMax(1); 129 | fractionSlider.setShowTickMarks(true); 130 | fractionSlider.setMajorTickUnit(0.1); 131 | fractionSlider.setMinorTickCount(0); 132 | HBox.setHgrow(fractionSlider, Priority.ALWAYS); 133 | fractionSlider.setMaxWidth(Double.MAX_VALUE); 134 | fractionSlider.valueProperty().bindBidirectional(startingPoint.fractionAlongEdgeProperty()); 135 | // configure a label that displays the fraction along edge value 136 | var fractionLabel = new Label(); 137 | fractionLabel.textProperty().bind(Bindings.format("%.2f", fractionSlider.valueProperty())); 138 | // add to the UI 139 | fractionHBox.getChildren().addAll(fractionSlider, fractionLabel); 140 | fractionTerminalsVBox.getChildren().add(fractionHBox); 141 | } 142 | 143 | if (terminalPickerVisible) { 144 | // configure a combobox that displays the available UtilityTerminal options 145 | ComboBox terminalsComboBox = new ComboBox<>(); 146 | terminalsComboBox.setMaxWidth(Double.MAX_VALUE); 147 | terminalsComboBox.setConverter(new StringConverter<>() { 148 | @Override 149 | public String toString(UtilityTerminal terminal) { 150 | return terminal != null ? terminal.getName() : ""; 151 | } 152 | @Override 153 | public UtilityTerminal fromString(String fileName) { 154 | return null; 155 | } 156 | }); 157 | terminalsComboBox.getItems().addAll( 158 | startingPoint.getUtilityElement().getAssetType().getTerminalConfiguration().getTerminals()); 159 | terminalsComboBox.getSelectionModel().select( 160 | startingPoint.getUtilityElement().getAssetType().getTerminalConfiguration().getTerminals().get(0)); 161 | terminalsComboBox.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { 162 | if (newValue != null) { 163 | startingPoint.getUtilityElement().setTerminal(newValue); 164 | } 165 | }); 166 | fractionTerminalsVBox.getChildren().add(terminalsComboBox); 167 | } 168 | } 169 | } 170 | } 171 | 172 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/com/esri/arcgisruntime/toolkit/skins/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | /** 18 | * Toolkit skins. 19 | */ 20 | package com.esri.arcgisruntime.toolkit.skins; 21 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/java/module-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | module com.esri.arcgisruntime.toolkit { 17 | // require ArcGIS Maps SDK for Java module 18 | requires com.esri.arcgisruntime; 19 | // require JavaFX modules required by this module 20 | requires transitive javafx.graphics; 21 | requires transitive javafx.controls; 22 | requires transitive javafx.fxml; 23 | 24 | // require other modules required by this module 25 | requires java.logging; 26 | 27 | exports com.esri.arcgisruntime.toolkit; 28 | exports com.esri.arcgisruntime.toolkit.skins; 29 | 30 | // allow FXML module access to Skin FXML files 31 | opens com.esri.arcgisruntime.toolkit.skins to javafx.fxml; 32 | } 33 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/resources/com/esri/arcgisruntime/toolkit/feature-template-picker.css: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | .feature-template-picker { 18 | -fx-spacing: 0; 19 | } 20 | 21 | .feature-template-picker:horizontal .feature-template-group { 22 | -fx-border-width: 0 1 0 0; 23 | } 24 | 25 | .feature-template-group { 26 | -fx-spacing: 5; 27 | -fx-padding: 5; 28 | -fx-alignment: top-center; 29 | -fx-border-color: -fx-box-border; 30 | -fx-border-width: 0 0 1 0; 31 | } 32 | 33 | .feature-template-item { 34 | -fx-text-fill: black; 35 | -fx-background-color: transparent; 36 | -fx-content-display: top; 37 | -fx-min-width: 80; 38 | } 39 | 40 | .feature-template-item:hover { 41 | -fx-background-color: -fx-hover-base; 42 | } -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/resources/com/esri/arcgisruntime/toolkit/floor-filter.css: -------------------------------------------------------------------------------- 1 | .floor-filter-view { 2 | -fx-background-color: #f4f4f4; 3 | -fx-border-color: grey; 4 | -fx-border-width: 1; 5 | } 6 | 7 | .floor-filter-sites VBox, .floor-filter-facilities VBox { 8 | -fx-spacing: 10; 9 | } 10 | 11 | .floor-filter-heading { 12 | -fx-font-weight: bold; 13 | } 14 | 15 | .floor-filter-levels { 16 | -fx-spacing: 10; 17 | -fx-padding: 10; 18 | } 19 | 20 | .floor-filter-zoom-button { 21 | -fx-min-height: 30; 22 | -fx-max-height: 30; 23 | } 24 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/main/resources/com/esri/arcgisruntime/toolkit/utility-network-trace.css: -------------------------------------------------------------------------------- 1 | /* Stylesheet containing styles applied to the Utility Network tool in a functional capacity */ 2 | * { 3 | -utility-network-view-trash-icon-svg: "M12.854 4h1.003l-.79 11.071a1.004 1.004 0 0 1-.999.929H3.932a1.004 1.004 0 0 1-.998-.93L2.143 4h1.003l.786 11h8.136zm-9.78-1H1V2h4V1a1.001 1.001 0 0 1 1-1h4a1.001 1.001 0 0 1 1 1v1h4v1H3.074zM6 2h4V1H6zm3.5 11a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-1 0v7a.5.5 0 0 0 .5.5zm-3 0a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-1 0v7a.5.5 0 0 0 .5.5"; 4 | -utility-network-view-trash-icon-color: black; 5 | -utility-network-view-zoom-icon-svg: "M15.293 16L12 12.707V15h-1v-4h4v1h-2.293L16 15.293zm0-16L12 3.293V1h-1v4h4V4h-2.293L16 .707zM8 6a2 2 0 1 1-2 2 2 2 0 0 1 2-2zm0 1a1 1 0 1 0 1 1 1 1 0 0 0-1-1zm-7 5h2.293L0 15.293.707 16 4 12.707V15h1v-4H1zm3-8.707L.707 0 0 .707 3.293 4H1v1h4V1H4z"; 6 | -utility-network-view-zoom-icon-color: black; 7 | -utility-network-view-warning-icon-svg: "M3.929 29h25.148a1.897 1.897 0 0 0 1.67-2.797L18.217 2.951a1.897 1.897 0 0 0-3.337-.005L2.261 26.198A1.897 1.897 0 0 0 3.93 29zm-.788-2.324L15.759 3.423a.896.896 0 0 1 1.577.002l12.531 23.253a.898.898 0 0 1-.79 1.322H3.93a.897.897 0 0 1-.788-1.324zM15.5 24.5a1 1 0 1 1 1 1 1.002 1.002 0 0 1-1-1zM17 21h-1V10h1z"; 8 | -utility-network-view-warning-icon-color: #EDD317; 9 | -utility-network-view-info-icon-svg: "M16.5 9.5a1 1 0 1 1 1-1 1.002 1.002 0 0 1-1 1zM17 23V12h-2v1h1v10h-1v1h3v-1zm12.8-6.5A13.3 13.3 0 1 1 16.5 3.2a13.3 13.3 0 0 1 13.3 13.3zm-1 0a12.3 12.3 0 1 0-12.3 12.3 12.314 12.314 0 0 0 12.3-12.3z"; 10 | -utility-network-view-info-icon-color: #00619B; 11 | -utility-network-view-error-icon-svg: "M16.5 24.5a1 1 0 1 1 1-1 1.002 1.002 0 0 1-1 1zM16 20h1V9h-1zm13.8-3.5A13.3 13.3 0 1 1 16.5 3.2a13.3 13.3 0 0 1 13.3 13.3zm-1 0a12.3 12.3 0 1 0-12.3 12.3 12.314 12.314 0 0 0 12.3-12.3z"; 12 | -utility-network-view-error-icon-color: #D83020; 13 | -utility-network-view-border-color: #CACACA; 14 | -utility-network-view-background-color: #FFFFFF; 15 | } 16 | 17 | .utility-network-view { 18 | -fx-border-color: -utility-network-view-border-color; 19 | -fx-border-width: 1; 20 | -fx-background-color: -utility-network-view-background-color; 21 | } 22 | 23 | .utility-network-view .arcgis-toolkit-java-trash-icon { 24 | -fx-shape: -utility-network-view-trash-icon-svg; 25 | -size: 20; 26 | -fx-background-color: -utility-network-view-trash-icon-color; 27 | -fx-min-height: -size; 28 | -fx-min-width: -size; 29 | -fx-max-height: -size; 30 | -fx-max-width: -size; 31 | } 32 | 33 | .utility-network-view .arcgis-toolkit-java-zoom-icon { 34 | -fx-shape: -utility-network-view-zoom-icon-svg; 35 | -fx-background-color: -utility-network-view-zoom-icon-color; 36 | -size: 20; 37 | -fx-min-height: -size; 38 | -fx-min-width: -size; 39 | -fx-max-height: -size; 40 | -fx-max-width: -size; 41 | } 42 | 43 | .utility-network-view .arcgis-toolkit-java-warning-icon { 44 | -fx-shape: -utility-network-view-warning-icon-svg; 45 | -size: 30; 46 | -fx-background-color: -utility-network-view-warning-icon-color; 47 | -fx-min-height: -size; 48 | -fx-min-width: -size; 49 | -fx-max-height: -size; 50 | -fx-max-width: -size; 51 | } 52 | 53 | .utility-network-view .arcgis-toolkit-java-info-icon { 54 | -fx-shape: -utility-network-view-info-icon-svg; 55 | -size: 30; 56 | -fx-background-color: -utility-network-view-info-icon-color; 57 | -fx-min-height: -size; 58 | -fx-min-width: -size; 59 | -fx-max-height: -size; 60 | -fx-max-width: -size; 61 | } 62 | 63 | .utility-network-view .arcgis-toolkit-java-error-icon { 64 | -fx-shape: -utility-network-view-error-icon-svg; 65 | -size: 30; 66 | -fx-background-color: -utility-network-view-error-icon-color; 67 | -fx-min-height: -size; 68 | -fx-min-width: -size; 69 | -fx-max-height: -size; 70 | -fx-max-width: -size; 71 | } 72 | 73 | .utility-network-view Label { 74 | -fx-wrap-text:true; 75 | } 76 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/test/java/com/esri/arcgisruntime/toolkit/FeatureTemplateGroupUnitTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit; 18 | 19 | import com.esri.arcgisruntime.data.ServiceFeatureTable; 20 | import com.esri.arcgisruntime.layers.FeatureLayer; 21 | import com.esri.arcgisruntime.toolkit.util.PlatformUtils; 22 | import javafx.application.Platform; 23 | import org.junit.jupiter.api.BeforeAll; 24 | import org.junit.jupiter.api.DisplayName; 25 | import org.junit.jupiter.api.Test; 26 | 27 | import java.util.concurrent.CountDownLatch; 28 | import java.util.concurrent.TimeUnit; 29 | 30 | import static org.junit.jupiter.api.Assertions.assertEquals; 31 | import static org.junit.jupiter.api.Assertions.assertFalse; 32 | import static org.junit.jupiter.api.Assertions.assertThrows; 33 | import static org.junit.jupiter.api.Assertions.assertTrue; 34 | 35 | /** 36 | * Feature template group unit tests. 37 | */ 38 | @DisplayName("feature template group unit tests") 39 | public class FeatureTemplateGroupUnitTest { 40 | 41 | private static final String WILDFIRE_RESPONSE_URL = "https://sampleserver6.arcgisonline" + 42 | ".com/arcgis/rest/services/Wildfire/FeatureServer/0"; 43 | 44 | private static final int LATCH_TIMEOUT_SEC = 10; 45 | 46 | /** 47 | * Starts the JavaFX platform before all tests. 48 | */ 49 | @BeforeAll 50 | private static void startPlatform() { 51 | if (!PlatformUtils.isPlatformStarted()) { 52 | Platform.startup(PlatformUtils::setPlatformStarted); 53 | } 54 | } 55 | 56 | /** 57 | * Tests constructor with a null feature layer. 58 | */ 59 | @Test 60 | @DisplayName("null feature layer throws") 61 | void nullFeatureLayer() { 62 | assertThrows(NullPointerException.class, () -> new FeatureTemplateGroup(null)); 63 | } 64 | 65 | /** 66 | * Tests the feature layer getter. 67 | */ 68 | @Test 69 | @DisplayName("can get feature layer via getter") 70 | void getFeatureLayer() { 71 | FeatureLayer featureLayer = new FeatureLayer(new ServiceFeatureTable(WILDFIRE_RESPONSE_URL)); 72 | FeatureTemplateGroup featureTemplateGroup = new FeatureTemplateGroup(featureLayer); 73 | assertEquals(featureLayer, featureTemplateGroup.getFeatureLayer()); 74 | } 75 | 76 | /** 77 | * Tests the feature layer property. 78 | */ 79 | @Test 80 | @DisplayName("can get feature layer via property") 81 | void featureLayerProperty() { 82 | FeatureLayer featureLayer = new FeatureLayer(new ServiceFeatureTable(WILDFIRE_RESPONSE_URL)); 83 | FeatureTemplateGroup featureTemplateGroup = new FeatureTemplateGroup(featureLayer); 84 | assertEquals(featureLayer, featureTemplateGroup.featureLayerProperty().get()); 85 | } 86 | 87 | /** 88 | * Tests that feature template items load asynchronously after construction. 89 | * 90 | * @throws InterruptedException exception 91 | */ 92 | @Test 93 | @DisplayName("feature template items load") 94 | void loadFeatureTemplateItems() throws InterruptedException { 95 | FeatureLayer featureLayer = new FeatureLayer(new ServiceFeatureTable(WILDFIRE_RESPONSE_URL)); 96 | FeatureTemplateGroup featureTemplateGroup = new FeatureTemplateGroup(featureLayer); 97 | assertEquals(0, featureTemplateGroup.getFeatureTemplateItems().size()); 98 | CountDownLatch countDownLatch = new CountDownLatch(1); 99 | featureLayer.addDoneLoadingListener(countDownLatch::countDown); 100 | assertTrue(countDownLatch.await(LATCH_TIMEOUT_SEC, TimeUnit.SECONDS)); 101 | assertFalse(featureTemplateGroup.getFeatureTemplateItems().isEmpty()); 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/test/java/com/esri/arcgisruntime/toolkit/FeatureTemplatePickerUnitTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit; 18 | 19 | import com.esri.arcgisruntime.data.ServiceFeatureTable; 20 | import com.esri.arcgisruntime.layers.FeatureLayer; 21 | import com.esri.arcgisruntime.toolkit.util.PlatformUtils; 22 | import javafx.application.Platform; 23 | import javafx.beans.property.ListProperty; 24 | import javafx.beans.property.SimpleListProperty; 25 | import javafx.collections.FXCollections; 26 | import javafx.collections.ObservableList; 27 | import org.junit.jupiter.api.BeforeAll; 28 | import org.junit.jupiter.api.DisplayName; 29 | import org.junit.jupiter.api.Test; 30 | 31 | import static org.junit.jupiter.api.Assertions.assertEquals; 32 | import static org.junit.jupiter.api.Assertions.assertThrows; 33 | 34 | /** 35 | * Feature template picker unit tests. 36 | */ 37 | @DisplayName("feature template picker unit tests") 38 | public class FeatureTemplatePickerUnitTest { 39 | 40 | private static final String WILDFIRE_RESPONSE_URL = "https://sampleserver6.arcgisonline" + 41 | ".com/arcgis/rest/services/Wildfire/FeatureServer/0"; 42 | 43 | /** 44 | * Starts the JavaFX platform before all tests. 45 | */ 46 | @BeforeAll 47 | private static void startPlatform() { 48 | if (!PlatformUtils.isPlatformStarted()) { 49 | Platform.startup(PlatformUtils::setPlatformStarted); 50 | } 51 | } 52 | 53 | /** 54 | * Tests constructor with a null observable feature layers list. 55 | */ 56 | @Test 57 | @DisplayName("constructor with null observable feature layers list") 58 | void nullObservableFeatureLayers() { 59 | assertThrows(NullPointerException.class, () -> new FeatureTemplatePicker((ObservableList) null)); 60 | } 61 | 62 | /** 63 | * Tests constructor with a null feature layer variable arg. 64 | */ 65 | @Test 66 | @DisplayName("constructor with null feature layer") 67 | void nullFeatureLayer() { 68 | assertThrows(NullPointerException.class, () -> new FeatureTemplatePicker((FeatureLayer) null)); 69 | } 70 | 71 | /** 72 | * Tests constructor with a feature layer array including null. 73 | */ 74 | @Test 75 | @DisplayName("constructor with null in feature layer array") 76 | void nullFeatureLayers() { 77 | assertThrows(NullPointerException.class, () -> new FeatureTemplatePicker(new FeatureLayer[]{null})); 78 | } 79 | 80 | /** 81 | * Tests that the features layers from the constructor can be retrieved via the getter. 82 | */ 83 | @Test 84 | @DisplayName("can get the feature layers") 85 | void getFeatureLayers() { 86 | FeatureLayer featureLayer = new FeatureLayer(new ServiceFeatureTable(WILDFIRE_RESPONSE_URL)); 87 | FeatureTemplatePicker featureTemplatePicker = new FeatureTemplatePicker(featureLayer); 88 | assertEquals(featureLayer, featureTemplatePicker.getFeatureLayers().get(0)); 89 | } 90 | 91 | /** 92 | * Tests that the picker can be backed by an observable list given to the constructor. 93 | */ 94 | @Test 95 | @DisplayName("layers backed by observable list") 96 | void observableFeatureLayersList() { 97 | ObservableList featureLayers = FXCollections.observableArrayList(); 98 | FeatureTemplatePicker featureTemplatePicker = new FeatureTemplatePicker(featureLayers); 99 | assertEquals(featureLayers, featureTemplatePicker.getFeatureLayers()); 100 | assertEquals(0, featureTemplatePicker.getFeatureLayers().size()); 101 | FeatureLayer featureLayer = new FeatureLayer(new ServiceFeatureTable(WILDFIRE_RESPONSE_URL)); 102 | featureLayers.add(featureLayer); 103 | assertEquals(1, featureTemplatePicker.getFeatureLayers().size()); 104 | assertEquals(featureLayer, featureTemplatePicker.getFeatureLayers().get(0)); 105 | } 106 | 107 | /** 108 | * Tests that feature layers can be added after initialization via the featureLayers observable list. 109 | */ 110 | @Test 111 | @DisplayName("add layers via observable list") 112 | void featureLayersObservableList() { 113 | FeatureTemplatePicker featureTemplatePicker = new FeatureTemplatePicker(); 114 | FeatureLayer featureLayer = new FeatureLayer(new ServiceFeatureTable(WILDFIRE_RESPONSE_URL)); 115 | featureTemplatePicker.getFeatureLayers().add(featureLayer); 116 | assertEquals(1, featureTemplatePicker.getFeatureLayers().size()); 117 | assertEquals(featureLayer, featureTemplatePicker.getFeatureLayers().get(0)); 118 | } 119 | 120 | /** 121 | * Tests that the feature layers list can be bound to an external list property. 122 | */ 123 | @Test 124 | @DisplayName("bind feature layers to external property") 125 | void bindFeatureLayersProperty() { 126 | ListProperty externalFeatureLayers = new SimpleListProperty<>(FXCollections.observableArrayList()); 127 | FeatureTemplatePicker featureTemplatePicker = new FeatureTemplatePicker(); 128 | featureTemplatePicker.featureLayersProperty().bind(externalFeatureLayers); 129 | FeatureLayer featureLayer = new FeatureLayer(new ServiceFeatureTable(WILDFIRE_RESPONSE_URL)); 130 | externalFeatureLayers.add(featureLayer); 131 | assertEquals(1, featureTemplatePicker.getFeatureLayers().size()); 132 | assertEquals(featureLayer, featureTemplatePicker.getFeatureLayers().get(0)); 133 | } 134 | 135 | /** 136 | * Tests that a binding can override the list the picker was initialized with. 137 | */ 138 | @Test 139 | @DisplayName("can bind over initialized list") 140 | void bindOverInitializeList() { 141 | FeatureLayer featureLayer = new FeatureLayer(new ServiceFeatureTable(WILDFIRE_RESPONSE_URL)); 142 | ObservableList featureLayers = FXCollections.observableArrayList(featureLayer); 143 | FeatureTemplatePicker featureTemplatePicker = new FeatureTemplatePicker(featureLayers); 144 | ListProperty emptyListProperty = new SimpleListProperty<>(FXCollections.observableArrayList()); 145 | featureTemplatePicker.featureLayersProperty().bind(emptyListProperty); 146 | assertEquals(0, featureTemplatePicker.getFeatureLayers().size()); 147 | } 148 | 149 | } 150 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/test/java/com/esri/arcgisruntime/toolkit/skins/FeatureTemplatePickerTilePaneSkinUnitTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.skins; 18 | 19 | import com.esri.arcgisruntime.toolkit.FeatureTemplatePicker; 20 | import com.esri.arcgisruntime.toolkit.util.PlatformUtils; 21 | import javafx.application.Platform; 22 | import javafx.geometry.Orientation; 23 | import javafx.scene.control.ScrollPane; 24 | import javafx.scene.layout.HBox; 25 | import javafx.scene.layout.VBox; 26 | import org.junit.jupiter.api.BeforeAll; 27 | import org.junit.jupiter.api.DisplayName; 28 | import org.junit.jupiter.api.Test; 29 | 30 | import static org.junit.jupiter.api.Assertions.assertEquals; 31 | import static org.junit.jupiter.api.Assertions.assertThrows; 32 | import static org.junit.jupiter.api.Assertions.assertTrue; 33 | 34 | /** 35 | * Feature template picker tile pane skin unit tests. 36 | */ 37 | @DisplayName("feature template picker tile pane skin unit tests") 38 | public class FeatureTemplatePickerTilePaneSkinUnitTest { 39 | 40 | /** 41 | * Starts the JavaFX platform before all tests. 42 | */ 43 | @BeforeAll 44 | static void startPlatform() { 45 | if (!PlatformUtils.isPlatformStarted()) { 46 | Platform.startup(PlatformUtils::setPlatformStarted); 47 | } 48 | } 49 | 50 | /** 51 | * Tests constructor with null argument throws null pointer. 52 | */ 53 | @Test 54 | @DisplayName("null control throws exception") 55 | void nullControlConstructor() { 56 | assertThrows(IllegalArgumentException.class, () -> new FeatureTemplatePickerTilePaneSkin(null)); 57 | } 58 | 59 | /** 60 | * Tests that skin correctly initializes its children. 61 | */ 62 | @Test 63 | @DisplayName("child nodes initialize") 64 | void initializesChildNodes() { 65 | FeatureTemplatePickerTilePaneSkin skin = new FeatureTemplatePickerTilePaneSkin(new FeatureTemplatePicker()); 66 | assertEquals(1, skin.getChildren().size()); 67 | assertTrue(skin.getChildren().get(0) instanceof ScrollPane); 68 | } 69 | 70 | /** 71 | * Tests that the content node inside the scroll pane changes orientation when the picker's orientation changes. 72 | */ 73 | @Test 74 | @DisplayName("content node changes when orientation changes") 75 | void contentNodeOrientation() { 76 | FeatureTemplatePicker featureTemplatePicker = new FeatureTemplatePicker(); 77 | FeatureTemplatePickerTilePaneSkin skin = new FeatureTemplatePickerTilePaneSkin(featureTemplatePicker); 78 | ScrollPane scrollPane = (ScrollPane) skin.getChildren().get(0); 79 | featureTemplatePicker.setOrientation(Orientation.HORIZONTAL); 80 | assertTrue(scrollPane.getContent() instanceof HBox); 81 | featureTemplatePicker.setOrientation(Orientation.VERTICAL); 82 | assertTrue(scrollPane.getContent() instanceof VBox); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /arcgis-java-toolkit/src/test/java/com/esri/arcgisruntime/toolkit/util/PlatformUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Esri 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.esri.arcgisruntime.toolkit.util; 18 | 19 | /** 20 | * Utilities for JavaFX platform. 21 | */ 22 | public class PlatformUtils { 23 | private static boolean platformStarted = false; 24 | 25 | /** 26 | * Checks if the platform started flag was set. 27 | * @return if the platform started flag was set. 28 | */ 29 | public static boolean isPlatformStarted() { 30 | return platformStarted; 31 | } 32 | 33 | /** 34 | * Sets the platform started flag to true. 35 | */ 36 | public static void setPlatformStarted() { 37 | PlatformUtils.platformStarted = true; 38 | } 39 | } 40 | --------------------------------------------------------------------------------