A lightweight pinch-to-zoom pane for JavaFX

Overview

GestureFX

Build Status License Download

A lightweight gesture enabled pane for JavaFX

Features

  • Accepts any Node or implementations of net.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
  • Works with both Java 8 and OpenJFX 11+

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.

How to use

For Maven users, add the following to pom

<dependency>
    <groupId>net.kurobako</groupId>
    <artifactId>gesturefx</artifactId>
    <version>0.6.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" % "0.6.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

Quick start

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.

Samples

Several samples have been included demoing interesting uses of the gesture pane.

JavaFX 8

You can download the sample jar here or clone the project and run:

./mvnw install
./mvnw exec:java -pl gesturefx-sample

OpenJFX 11+

Make sure you have at least JDK 11 installed:

> java -version
openjdk version "11.0.4" 2019-07-16
OpenJDK Runtime Environment 18.9 (build 11.0.4+11)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.4+11, mixed mode, sharing)

Run the sample jar with the following:

java -Dglass.gtk.uiScale=200% --module-path path/to/javafx-sdk-13/lib --add-modules javafx.controls,javafx.fxml,javafx.web,javafx.swing -jar gesturefx-sample-0.6.0-jar-with-dependencies.jar

See https://openjfx.io/openjfx-docs/#install-javafx for more details.

The -Dglass.gtk.uiScale=200% flag is optional if OpenJFX does not detect HiDPI monitors automatically. On Windows the flag should be -Dglass.win.uiScale=N%.

How to build

To ensure the project is usable with Java 8 and OpenJFX, you must build against Java 8.

Prerequisites:

  • JDK 8 with JavaFX

Be aware that some OpenJDK distributions does not include JavaFX or have missing webkit libraries which is required for the sample to build.

Clone the project and then in project root:

# *nix:
./mvnw clean package 
# Windows:
mvnw clean package

If JDK 8 is not your main JDK, prepend the correct JAVA_HOME before any maven command (e.g JAVA_HOME=/usr/java/jdk1.8.0_161/ mvn clean compile).

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.

Release process

  1. Commit all changes before release

  2. Make sure ${user.home}/.m2/settings.xml exist, if not copy it from maven home (i.e cp usr/share/maven/conf/settings.xml ~/.m2/settings.xml ) and add the following section to <servers></servers>:

    <server>
      <id>bintray-${bintray.user}-maven</id>
      <username>${bintray-username}</username>
      <password>${bintray-api-key}</password>
    </server>

    Look up bintray-api-key and bintray-username in the bintray profile page, also make sure machine has SSH access to GitHub

  3. Run mvn release:prepare -DdryRun=true, make sure it succeeds and then run mvn release:clean

  4. Run mvn release:prepare, maven will tag and commit the new version. Inspect the commits and do a push, also push the tags via git push --tags

  5. Finally, run mvn clean release:perform to create docs and sources and upload to bintray

Motivation

Someone has to do it.

Acknowledgements

Features or designs of this library was originally developed as part of an undergraduate coursework assignment at the University of Bristol.

YourKit supports the GestureFX project with its full-featured Java Profiler. YourKit, LLC is the creator YourKit Java Profiler and YourKit .NET Profiler, innovative and intelligent tools for profiling Java and .NET applications.

Licence

Copyright 2020 WeiChen 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.
Comments
  • How to get wdith of image or pane after and during zooming?

    How to get wdith of image or pane after and during zooming?

    System.out.println(pane.getCurrentScale()); shows the current scale factor of the image while zooming,

    how can I get the actual width as it is zoomed?

    opened by taibhse-designs 5
  • Migrate from jcenter

    Migrate from jcenter

    Hi @tom91136!

    First of all, thanks for this awesome library, it's really useful!

    GestureFX is distributed on jcenter. The problem is that JFrog announced that they will be shutting down Bintray and JCenter, so you should migrate to a different alternative.

    Now I use JitPack for downloading your library:

    repositories {
    	...
    	maven { url 'https://jitpack.io' }
    }
    
    dependencies {
    	 implementation 'com.github.tom91136.GestureFX:gesturefx:gesturefx-parent-0.6.0'
    }
    
    

    Best regards

    opened by Dansoftowner 1
  • Zooming out by scrolling moves too slowly

    Zooming out by scrolling moves too slowly

    Zooming out by scrolling moves too slowly while zooming in moves at expected amount. I think the issue here is at this code from line 288:

      case ZOOM:
    	  double zoomFactor = DEFAULT_SCROLL_FACTOR * pane.scrollZoomFactor.get();
    	  if (e.getDeltaY() < 0) zoomFactor *= -1;
    	  pane.scale(1 + zoomFactor, fromGesture(e));
    	  break;
    

    Why is it adding +1 to the zoomFactor?

    Also how can I change my code to get this desired result? I think I will have to override the scrolling event but I don't want rewrite that whole section.

    opened by Vis5 1
  • Bump junit from 4.12 to 4.13.1 in /gesturefx

    Bump junit from 4.12 to 4.13.1 in /gesturefx

    Bumps junit from 4.12 to 4.13.1.

    Release notes

    Sourced from junit's releases.

    JUnit 4.13.1

    Please refer to the release notes for details.

    JUnit 4.13

    Please refer to the release notes for details.

    JUnit 4.13 RC 2

    Please refer to the release notes for details.

    JUnit 4.13 RC 1

    Please refer to the release notes for details.

    JUnit 4.13 Beta 3

    Please refer to the release notes for details.

    JUnit 4.13 Beta 2

    Please refer to the release notes for details.

    JUnit 4.13 Beta 1

    Please refer to the release notes for details.

    Commits
    • 1b683f4 [maven-release-plugin] prepare release r4.13.1
    • ce6ce3a Draft 4.13.1 release notes
    • c29dd82 Change version to 4.13.1-SNAPSHOT
    • 1d17486 Add a link to assertThrows in exception testing
    • 543905d Use separate line for annotation in Javadoc
    • 510e906 Add sub headlines to class Javadoc
    • 610155b Merge pull request from GHSA-269g-pwp5-87pp
    • b6cfd1e Explicitly wrap float parameter for consistency (#1671)
    • a5d205c Fix GitHub link in FAQ (#1672)
    • 3a5c6b4 Deprecated since jdk9 replacing constructor instance of Double and Float (#1660)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • Scrolling and Zooming

    Scrolling and Zooming

    The default behavior of the GesturePane seems to exclusively register zoom gestures. Is there a way to add rotation and translation support to fully resemble the behavior of mobile UIs? On Android and iOS the pinch to zoom is often also used to trigger a full transformation (translate, zoom, rotate).

    opened by miho 1
Owner
Tom Lin
Tom Lin
A lightweight RCP framework for JavaFX applications.

WorkbenchFX The one and only framework to build large JavaFX Applications! Maven To use this framework as part of your Maven build simply add the foll

DLSC Software & Consulting GmbH 471 Jan 8, 2023
Tray Icon implementation for JavaFX applications. Say goodbye to using AWT's SystemTray icon, instead use a JavaFX Tray Icon.

FXTrayIcon Library intended for use in JavaFX applications that makes adding a System Tray icon easier. The FXTrayIcon class handles all the messy AWT

Dustin Redmond 248 Dec 30, 2022
Lib-Tile is a multi Maven project written in JavaFX and NetBeans IDE 8 and provides the functionalities to use and handle easily Tiles in your JavaFX application.

Lib-Tile Intention Lib-Tile is a multi Maven project written in JavaFX and NetBeans IDE and provides the functionalities to use and handle easily Tile

Peter Rogge 13 Apr 13, 2022
DataFX - is a JavaFX frameworks that provides additional features to create MVC based applications in JavaFX by providing routing and a context for CDI.

What you’ve stumbled upon here is a project that intends to make retrieving, massaging, populating, viewing, and editing data in JavaFX UI controls ea

Guigarage 110 Dec 29, 2022
an open souece, lightWeight and beautiful GUI for VPN Usage

free, open source, lightweight and beutiful GUI for vpn usage , this Project is part of my #100DaysOfCode challenge in twitter : @My_Terminal Dependen

Mohammad Esmaeili 21 Nov 9, 2022
Lightweight installer written in java, made for minecraft mods, The installer uses JPanel and uses a URL to install to the specific area (Discord URL's work the best i've seen)

InstallerForJava Lightweight installer written in java, made for minecraft mods, The installer uses JPanel and uses a URL to install to the specific a

null 18 Dec 9, 2022
Collection of Binding helpers for JavaFX(8)

Advanced-Bindings for JavaFX (8) advanced-bindings is a collection of useful helpers and custom binding implementations to simplify the development of

Manuel Mauky 63 Nov 19, 2022
Docking framework for JavaFX platform

Docking framework for JavaFX platform AnchorFX is a gratis and open source library for JavaFX to create graphical interfaces with docking features Anc

Alessio Vinerbi 197 Oct 15, 2022
A library of +70 ready-to-use animations for JavaFX

AnimateFX A library of ready-to-use animations for JavaFX Features: Custom animations Custom interpolators Play/Stop animation Play an animation after

Loïc Sculier 366 Jan 5, 2023
BootstrapFX: Bootstrap for JavaFX

BootstrapFX BootstrapFX is a partial port of Twitter Bootstrap for JavaFX. It mainly provides a CSS stylesheet that closely resembles the original whi

Kordamp 810 Dec 28, 2022
A Java framework for creating sophisticated calendar views (JavaFX 8, 9, 10, and 11)

CalendarFX A Java framework for creating sophisticated calendar views based on JavaFX. A detailed developer manual can be found online: CalendarFX 8 D

DLSC Software & Consulting GmbH 660 Jan 6, 2023
Allow runtime modification of JavaFX CSS

cssfx ⚠ WARNING ⚠ In version 11.3.0 we have relocated & refactored the project. maven groupId has been changed to fr.brouillard.oss java module name h

Matthieu Brouillard 134 Jan 2, 2023
A JavaFX UI framework to create fully customized undecorated windows

CustomStage A JavaFX undecorated stage which can fully be customized Donations If this project is helpful to you and love my work and feel like showin

Oshan Mendis 186 Jan 6, 2023
MDI components for JavaFX

DesktopPaneFX DesktopPaneFX is a JavaFX version of Swing’s JDesktopPane which can be used as a container for individual "child" similar to JInternalFr

Kordamp 58 Sep 23, 2022
Efficient VirtualFlow for JavaFX

Flowless Efficient VirtualFlow for JavaFX. VirtualFlow is a layout container that lays out cells in a vertical or horizontal flow. The main feature of

null 163 Nov 24, 2022
A framework for easily creating forms for a JavaFX UI.

FormsFX Forms for business application made easy. Creating forms in Java has never been this easy! Maven To use this framework as part of your Maven b

DLSC Software & Consulting GmbH 534 Dec 30, 2022
:icecream: iOS frosty/translucent effect to JavaFX

FroXty is JavaFX library which replicates the famous iOS translucent effect with ease. Set-up FroXty can be imported into your project either by downl

Giorgio Garofalo 33 Dec 11, 2022
💠 Undecorated JavaFX Scene with implemented move, resize, minimise, maximise, close and Windows Aero Snap controls.

Support me joining PI Network app with invitation code AlexKent FX-BorderlessScene ( Library ) ?? Undecorated JavaFX Scene with implemented move, resi

Alexander Kentros 125 Jan 4, 2023
Dynamic JavaFX form generation

FXForm 2 Stop coding forms: FXForm 2 can do it for you! About FXForm2 is a library providing automatic JavaFX form generation. How does it work? Write

dooApp 209 Jan 9, 2023