PitchHut logo
swing-fluid-swipe
'Safari-Like' 2-Finger Nav Gestures for AWT/Swing & JetBrains: Solving a 14-Year Gap for 15M Users
Pitch

This library provides native-like UI/UX for applications used by over 15 million developers worldwide. We’ve made possible the one feature users have been waiting for since 2010: native 2-finger navigation gestures on macOS (Google: JBR-4083).

Video Demo: https://bit.ly/swing-fluid-swipe-demo.

Description

SwingFluidSwipeAPI

Enhance your Java AWT/Swing applications with fluid-swipe gesture support, bridging the gap between native applications and AWT/Swing interfaces. This project aims to provide a consistent and enjoyable user experience through animated feedback, mimicking the fluid-swipe gestures prevalent in macOS applications.

Features

  • Fluid-Swipe Gesture Support: Integrate fluid-swipe gestures commonly utilized in macOS applications, improving navigation and interaction.
  • Event Monitoring: Easily monitor for fluid-swipe gestures with simple function calls.

macOS/OS X Compatibility

The Java Development Kit (JDK) lacks support for fluid-swipe gestures, which are an essential part of user interaction in many macOS applications such as Safari and Xcode. This project addresses that limitation by enabling these gestures in AWT/Swing applications.

Usage

To integrate swing-fluid-swipe, add the dependency to your build tool:

Maven:

<dependency>
  <groupId>eu.giulianogorgone</groupId>
  <artifactId>fluidswipe-core</artifactId>
  <version>1.2.0</version>
</dependency>

Gradle:

implementation("eu.giulianogorgone:fluidswipe-core:1.2.0")

Start event monitoring with:

FluidSwipe.startEventMonitoring();

To stop monitoring:

FluidSwipe.stopEventMonitoring();

Configuring Gesture Listeners

Implement gesture listeners in components to handle fluid-swipe events seamlessly:

import javax.swing.*;

public class NavigableComponent extends JComponent implements FluidSwipeVetoer {
  protected void configGestures() {
    FluidSwipe.addListenerTo(this, new FluidSwipeAdapter() {
      @Override
      public void fluidSwipeEnded(final FluidSwipeEvent e) {
        if (e.getGestureState() == FluidSwipeEvent.State.SUCCESS) {
          if (contentDirection == FluidSwipeEvent.Direction.LEFT_TO_RIGHT)
            this.navigateBack();
          else this.navigateForward();
        }
      }
    });
  }
  
  @Override
  public boolean permitFluidSwipeGesture(final FluidSwipeEvent e) {
    return (e.getLogicalGestureDirection() == FluidSwipeEvent.Direction.LEFT_TO_RIGHT)
            ? this.canNavigateBack() : this.canNavigateForward();
  }
}

A runnable sample is available here.

macOS/OS X Settings for Fluid-Swipe Support

Ensure the following settings are configured for trackpads and mice to support fluid-swipe gestures:

  1. For Trackpads:
    • Enable scrolling in system preferences.
    • Select swipe gestures from the trackpad settings.
  2. For Mice:
    • Enable scrolling options in system preferences.
    • Select appropriate swipe gestures in the trackpad settings.

Glossary

  • Veto a fluid-swipe: Preventing a physical swipe gesture from being interpreted as a fluid-swipe, allowing it to be handled as a regular scroll gesture.
  • Swipeable Component: A Swing component configured to handle fluid-swipe events.
  • Vetoer Component: A Swing component that implements the FluidSwipeVetoer interface, enabling the capability to veto incoming fluid-swipe events.

Avoiding Gesture Conflicts

Implement a coexistence mechanism for scroll and fluid-swipe gestures to ensure both functionalities work harmoniously:

public class FluidSwipeAwareJScrollPane extends JScrollPane implements FluidSwipeVetoer {
  @Override
  public boolean permitFluidSwipeGesture(FluidSwipeEvent e) {
    final FluidSwipeEvent.Direction contentDirection = e.getLogicalGestureDirection();
    if (horizontalScrollBar == null || getHorizontalScrollBarPolicy() == HORIZONTAL_SCROLLBAR_NEVER) return true;
    return (contentDirection == FluidSwipeEvent.Direction.RIGHT_TO_LEFT && (horizontalScrollBar.getValue() + horizontalScrollBar.getModel().getExtent()) == horizontalScrollBar.getMaximum())
            || (contentDirection == FluidSwipeEvent.Direction.LEFT_TO_RIGHT && horizontalScrollBar.getValue() == horizontalScrollBar.getMinimum());
  }
}

Starting with version 1.2.0, this logic is applied by default to JScrollPane components.

Hardware/Software Requirements

  • Operating System: macOS/OS X version 10.13 or later.
  • Hardware: Compatible with Apple Magic Trackpad and Mac laptops' built-in trackpads. Compatibility with Apple Magic Mouse is expected but not yet tested.

Contribution Guidelines

For contributed improvements or issues, please provide detailed information about reproducibility and your environment:

  • Running machine details (macOS/OS X version, JDK version, architecture)
  • Steps to reproduce the issue
  • A clear written description of the problem

Maintain professionalism by following appropriate conduct in all communications. Any inappropriate content will be reported.

Future Enhancements

Planned features include ensuring functionality for Magic Mouse and expanding support for additional platforms.

0 comments

No comments yet.

Sign in to be the first to comment.