A lightweight gesture enabled pane for JavaFX
Features
- Accepts any
Node
or implementations ofnet.kurobako.gesturefx.GesturePane.Transformable
- Pinch-to-zoom
- Configurable behavior for trackpad events
- Works with touch screen devices
- Works in Swing via JFXPanel
- Zoom/scroll to coordinate with animations
- Mostly works in SceneBuilder*
- Zero dependency
For comparison, this library is similar to PhotoView
for Android but supports gestures on any Node
subclass.
*SceneBuilder renders the control properly and all the exposed properties are editable in the
sidebar. Unfortunately, I have no idea how to make SceneBuilder treat this control as a
container/control so the only way to add GesturePane
to your FXML is to add it in XML and then
open it in SceneBuilder. Pull requests welcome on solving this.
For Maven users, add the following to pom
<dependency>
<groupId>net.kurobako.gesturefx</groupId>
<artifactId>gesturefx</artifactId>
<version>0.2.0</version>
</dependency>
You also need to add jcenter repo to your pom:
<repositories>
<repository>
<id>jcenter</id>
<url>https://jcenter.bintray.com/</url>
</repository>
</repositories>
For SBT
"net.kurobako.gesturefx" % "gesturefx" % "0.2.0"
And also jcenter:
resolvers ++= Seq(Resolver.jcenterRepo)
Alternatively, you can download the jar here and add it to your classpath. This library has no dependencies so you do not need to download anything else.
Version history in available in CHANGELOG.md
Adding an ImageView
to GesturePane
:
Node node = new ImageView(getClass().getResource("/lena.png").toExternalForm());
GesturePane pane = new GesturePane(node);
Translate or zoom:
GesturePane pane = //...
// zoom to 1x
pane.zoomTo(1);
// centre on point [42,42]
pane.centreOn(new Point2D(42, 42));
And with animations:
pane.animate(Duration.millis(200)).zoomTo(1);
// animate with some options
pane.animate(Duration.millis(200))
.interpolateWith(Interpolator.EASE_BOTH)
.beforeStart(() -> System.out.println("Starting..."))
.afterFinished(() -> System.out.println("Done!"))
.centreOn(new Point2D(42, 42));
Double click to zoom in:
// zoom*2 on double-click
GesturePane pane = //...
pane.setOnMouseClicked(e -> {
if (e.getButton() == MouseButton.PRIMARY && e.getClickCount() == 2) {
Point2D pivotOnTarget = pane.targetPointAt(new Point2D(e.getX(), e.getY()))
.orElse(pane.targetPointAtViewportCentre());
// increment of scale makes more sense exponentially instead of linearly
pane.animate(Duration.millis(200))
.interpolateWith(Interpolator.EASE_BOTH)
.zoomBy(pane.getCurrentScale(), pivotOnTarget);
}
});
For more interesting examples, take a look at the samples.
Several samples have been included demoing interesting uses of the gesture pane.
You can download the sample jar here or clone the project and run:
./mvnw install
./mvnw exec:java -pl gesturefx-sample
Prerequisites:
- JDK 8
Clone the project and then in project root:
# *nix:
./mvnw clean package
# Windows:
mvnw clean package
This project uses maven wrapper so you do not need to install maven beforehand.
For testing on new platforms, it is recommended to run tests headful. Add the headful flag to test with real window:
mvnw test -Dheadful
NOTE: Be aware that running the tests headful will spawn actual windows and take over the mouse and keyboard; you will see the test window flicker while different unit tests are invoked.
Someone has to do it.
Features or designs of this library was originally developed as part of an undergraduate coursework assignment at the University of Bristol.
Copyright 2017 WEI CHEN LIN
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.