A modern Java 21 / JavaFX implementation of the Graph Digitizer tool for extracting numeric data points from raster images of graphs.
1.1 (Java Edition)
-
Quick Reference Guide - Commands, shortcuts, and common tasks
-
Developer Guide - Architecture, patterns, and extension guide
-
Project Summary - Complete project overview
-
Index - Comprehensive documentation index
-
Accessibility Overview - Complete accessibility features guide
-
Quick Start - Get started with screen readers
-
Implementation Guide - Technical implementation details
-
Implementation Complete - âś… All audit fixes applied
-
Low Vision Audit - Comprehensive accessibility audit results
-
Summary - Features and capabilities overview
-
Checklist - Verification and testing checklist
-
Quick Reference - Theme selection guide
-
Implementation - Technical details
-
Packaging Guide - AppImage, DEB, RPM, and native installers
-
jlink / jpackage Guide - How to create runtime images, cross-arch examples (Docker), and use
jpackagefor native installers.
-
scripts/README.md- Quick reference for thescripts/helpers (jpackage wrappers) and how to produce OS installers. This includes the Windows MSI generator (scripts/generate-msi.ps1) which can produce per-architecture MSIs when supplied with matching runtime images; outputs are placed undertarget/generated_builds. -
docs/JPACKAGE.md- Extended guide forjlinkandjpackage, cross-arch runtime image creation (including Docker examples), and CI recommendations.
-
Latest API (Javadoc) – Generated from the current main branch
-
Versioned Archives: Each release will publish Javadocs under a subdirectory (e.g.
/1.1/,/1.2/). Navigate directly to a version path to view older APIs.
- Java 21 or later jpackage --type dmg --name GraphDigitizer --main-jar graph_digitizer_1.0.jar \
Note: This project uses JavaFX 21 and therefore either the user's JDK should
contain JavaFX modules (e.g., a Liberica Full JDK) or the build will need
to download platform-specific JavaFX artifacts (handled by Maven profiles in
the pom.xml).
-
Clone or download the repository
-
Navigate to the project directory
-
Build the project:
mvn clean package
```
### Running the Application
Using Maven:
```bash
mvn javafx:run
```
Or run the JAR directly:
```bash
java -jar target/graph_digitizer_1.0-beta.jar
```
If you want to distribute a "clickable" application that does not require the
end user to install Java, see "Packaging & Distribution" below.
## Features
- **Load Images**: Load raster images of graphs for digitization
- **Non-blocking Calibration**: Record four clicks to establish coordinate mapping
- **Manual Point Editing**: Left-click to add points, right-click or Delete to remove
- **Precision Placement**: Zoom and magnifier tools for pixel-level accuracy (planned)
- **Auto-trace**: Automatically extract curve points using color matching
- **Multiple Datasets**: Support for up to 6 color-coded datasets
- **Linear & Log Scales**: Support for both linear and logarithmic axes
- **Export Formats**: Save to JSON (full metadata) or CSV (tabular data)
- **Responsive UI**: Modern JavaFX interface with intuitive controls
## Example Session & Assets
The `docs/README_Assets` folder contains a screenshot from a sample digitization session and the raw data files produced during that session. The assets were moved into the documentation directory so they are versioned with the project.
- **Screenshot (inline):**

- **Session data (raw files):**
- CSV: [Sample_Graph_20251119-073453.csv](docs/README_Assets/Sample_Graph_20251119-073453.csv)
- JSON: [Sample_Graph_20251119-073453.json](docs/README_Assets/Sample_Graph_20251119-073453.json)
Inline examples (small excerpts):
CSV excerpt:
```csv
x,Linear,InverseLinear,zigzag,nil,Mountain,Dataset 6
1,0.13245033112582782,-0.033112582781456956,-0.033112582781456956,0,0.16556291390728478,
2,0.9602649006622516,15.132450331125828,0.8940397350993378,0.9271523178807948,1.0596026490066226,
3,1.9867549668874174,14.072847682119205,2.185430463576159,0.9271523178807948,1.0264900662251657,
JSON excerpt:
{
"title": "Sample Graph",
"xlabel": "X values (0-15)",
"ylabel": "Y values (0-15)",
"x_min": 0.0,
"x_max": 15.0
}
Additional example files demonstrating common cases:
-
Log-scaled X axis example (CSV/JSON):
-
Missing values example (CSV/JSON):
├── pom.xml # Maven configuration
├── src/
│ │ ├── java/com/digitizer/
│ │ │ ├── core/ # Core business logic (no GUI dependencies)
│ │ │ │ ├── Point.java
│ │ │ │ ├── Dataset.java
│ │ │ │ ├── CalibrationState.java
│ │ │ │ ├── CoordinateTransformer.java
│ │ │ │ ├── ColorUtils.java
│ │ │ │ └── FileUtils.java
│ │ │ ├── image/ # Image processing
│ │ │ │ ├── ImageLoader.java
│ │ │ │ └── AutoTracer.java
│ │ │ ├── io/ # File I/O
│ │ │ │ ├── ProjectJson.java
│ │ │ │ ├── DatasetJson.java
│ │ │ │ ├── JsonExporter.java
│ │ │ │ └── CsvExporter.java
│ │ │ └── ui/ # User Interface
│ │ │ ├── GraphDigitizerApp.java
│ │ │ ├── MainWindow.java
│ │ │ ├── CanvasPanel.java
│ │ │ ├── ControlPanel.java
│ │ │ └── StatusBar.java
│ │ └── resources/
│ │ ├── fxml/ # JavaFX FXML files (future)
│ │ └── css/ # Stylesheets (future)
│ └── test/
│ └── java/com/digitizer/ # Unit tests
│ ├── core/
│ └── io/
└── target/ # Build output
Pure business logic with no GUI dependencies:
-
Point: Immutable record representing a single data point (x, y)
-
Dataset: Mutable collection of points with metadata (name, color)
-
CalibrationState: Manages calibration anchors and numeric axis ranges
-
CoordinateTransformer: Transforms between data and canvas coordinates (supports log scales)
-
ColorUtils: Color parsing, distance calculations, and blending
-
FileUtils: Filename sanitization, defaults, and file operations
Image loading and automatic curve extraction:
-
ImageLoader: Loads PNG/JPEG images from files
-
AutoTracer: Column-by-column color matching for curve extraction
-
ProjectJson / DatasetJson: POJO models for JSON serialization
-
JsonExporter: Full-fidelity JSON format with metadata and log flags
-
CsvExporter: Wide-format CSV export for spreadsheet compatibility
JavaFX-based graphical interface:
-
GraphDigitizerApp: Application entry point and lifecycle management
-
MainWindow: Main window orchestration and menu bar
-
CanvasPanel: Image display, point visualization, and user interaction
-
ControlPanel: Dataset and calibration controls
-
StatusBar: Status message display
Click "Load Image" button and select a PNG or JPEG file containing the graph.
-
Click "Calibrate" button
-
Click four points on the image in order:
- Y-top: top known y-axis position
-
Enter numeric axis ranges (X min/max, Y min/max)
-
Toggle "X Log" / "Y Log" if axes are logarithmic
-
Click "Apply Calibration"
-
Left-click: Add a point at that location
-
Drag: Move an existing point
-
Right-click: Delete a point (or press Delete/Backspace)
Select a dataset and click "Auto Trace". The algorithm scans columns and selects pixels matching the dataset color.
Note: Auto Trace is guarded by a runtime feature flag. If the Auto Trace controls are disabled, enable them via the menu: Actions -> Enable Auto Trace. The toggle updates the toolbar button and menu item immediately without restarting the app. This allows you to safely keep the unfinished Auto Trace implementation hidden until you're ready to use it.
-
Save JSON: Full project with metadata and all datasets
-
Save CSV: Tabular format suitable for spreadsheets and further analysis
{
"x_min": 0.0,
"x_max": 100.0,
"y_min": -1.0,
"y_max": 1.0,
"x_log": false,
"y_log": false,
"datasets": [
{
"name": "Dataset 1",
"color": "#0072B2",
"points": [[0.0, 0.1], [1.0, 0.15], ...]
}
]
}
Wide-format with x values in the first column:
x,Dataset_1,Dataset_2
0.0,0.1,-0.05
1.0,0.15,
2.5,,0.2
# Clean and package
mvn clean package
# Create executable JAR with dependencies
mvn package
# Run tests
mvn test
# Run the application
mvn javafx:run
Use Maven's javadoc plugin to generate API documentation based on the
Javadoc comments added throughout the codebase. This creates an "apidocs"
folder with HTML files under target/site.
mvn javadoc:javadoc
# Open the docs in your browser
start target/site/apidocs/index.html # Windows
open target/site/apidocs/index.html # macOS
xdg-open target/site/apidocs/index.html # Linux
This project is a JavaFX desktop application and shipping a cross-platform
installer or a single binary is commonly done using jlink + jpackage.
Below are recommended options for creating a clickable, distributable
application on macOS, Linux, and Windows.
- Add the Maven Shade plugin to your
pom.xmlto build a "fat" JAR bundling all libraries (not native JavaFX OS libs). Example inpom.xml:
<!-- snippet: put inside <build><plugins> -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.4.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.digitizer.ui.GraphDigitizerApp</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
- Then build the artifact:
mvn clean package
# Resulting file in target/ will be a shaded jar, try:
java -jar target/graph_digitizer_1.0-beta.jar
Notes:
-
A standard fat JAR will still require the end user to have a compatible Java runtime installed. For JavaFX, you still need the JavaFX runtime for the target OS if not bundled.
-
For a fully self-contained native app (recommended), use Option B.
This approach uses jlink to create a custom runtime image and jpackage
to generate an OS-specific package (DMG, PKG, DEB, RPM, EXE, MSI).
Maven can call both of these tools via plugin configuration or use the
jlink and jpackage CLIs directly with a JDK that supports them.
You will need a JDK 21 distribution (for example Azul, Adoptium or Liberica)
installed that contains jlink and jpackage tools.
Basic flow (CLI approach):
- Create runtime image with required modules (JavaFX modules and your app):
# Example for macOS/Linux/Windows - adjust module list and paths
jlink --module-path $JAVA_HOME/jmods:target/lib --add-modules java.base,java.desktop,java.logging,javafx.controls,javafx.graphics --output custom-runtime
- Build an app image with jpackage (Windows example creating an exe):
jpackage --type exe \
--input target/ \
--name GraphDigitizer \
--main-jar graph_digitizer_1.0-beta.jar \
--main-class com.digitizer.ui.GraphDigitizerApp \
--runtime-image custom-runtime \
--icon build/icons/graphdigitizer.ico
-
For macOS, use
--type dmgor--type pkgand--iconas .icns. -
For Linux, use
--type debor--type rpm, or create an AppImage.
Tip: Use maven-jlink-plugin and the jpackage Maven plugin to integrate
this into your Maven lifecycle so OS-specific packages are reproducible.
The repository includes a unified Maven packaging setup driven by the native property. A single command now builds the shaded JAR, copies icons, gathers JavaFX modules for the current OS, creates the jpackage app-image, and then produces any OS-specific installers.
Unified build command (run this on your current OS):
mvn clean package -Dnative
- Outputs per OS:
Windows:
-
App image:
target/jpackage/GraphDigitizer -
MSI installer:
target/jpackage-msi/GraphDigitizer-<version>.msi
macOS:
-
App image:
target/jpackage/GraphDigitizer.app -
DMG installer:
target/jpackage-dmg/GraphDigitizer-<version>.dmg
Linux:
-
App image:
target/jpackage/GraphDigitizer -
DEB package:
target/jpackage-deb/graphdigitizer_<version>_amd64.deb(name may vary by architecture) -
RPM package:
target/jpackage-rpm/graphdigitizer-<version>-1.x86_64.rpm(name may vary by architecture)
Optional overrides (examples):
mvn clean package -Dnative -Dicon.win=build/icons/custom.ico
mvn clean package -Dnative -Dicon.mac=build/icons/custom.icns
mvn clean package -Dnative -Dicon.linux=build/icons/custom.png
(Icon properties default to the copied files under build/icons.)
Skip tests if desired:
mvn clean package -Dnative -DskipTests
If you only want to adjust version or icon without rebuilding everything, you can reuse the previous target artifacts; however, the unified command is designed to be reproducible and idempotent.
Advanced: You can still run jpackage manually for debugging; see the manual section below.
(Deprecated examples removed: previous per-OS -Pnative + -Djpackage.type usage has been replaced by the single -Dnative flow.)
Notes:
-
Set
-Dicon=path/to/iconto provide a custom icon for the installer. -
Run packaging on the target OS (Windows packages on Windows, macOS on macOS) for best results.
Windows MSI creation is automatic with:
mvn clean package -Dnative
(Previous instructions using -Pnative and -Djpackage.type are obsolete.)
-
Install the WiX Toolset (v3.11 or v4+) and ensure
candle.exe/light.exe(or equivalent WiX binaries) are on yourPATH. -
Recommended quick command (PowerShell) — full automated flow using the
nativeMaven profile:
# Ensure JAVA_HOME is set and points to a JDK that includes `jpackage` (Java 21+ or Semeru/Adoptium with tools)
echo $Env:JAVA_HOME
& "$Env:JAVA_HOME\bin\java" -version
# Optional: remove any previous app-image to avoid conflicts
if (Test-Path 'target\jpackage\GraphDigitizer') { Remove-Item -Recurse -Force 'target\jpackage\GraphDigitizer' }
# Build MSI with the native profile (runs jpackage via the POM)
mvn -Pnative -DskipTests -Djpackage.type=msi -Dicon.win=build/icons/scatter-plot-256.ico package
- Manual two-step
jpackage(if you need to debug or runjpackageyourself):
# Create the app-image (bundles the runtime libs and application)
& "$Env:JAVA_HOME\bin\jpackage.exe" --type app-image \
--input target/jpackage-input \
--main-jar graph-digitizer.jar \
--main-class com.digitizer.ui.GraphDigitizerApp \
--name GraphDigitizer \
--dest target/jpackage \
--icon build/icons/scatter-plot-256.ico \
--app-version 1.1 \
--java-options "--module-path $APPDIR\\lib" \
--java-options "--add-modules=javafx.controls,javafx.fxml,javafx.swing"
# Build the MSI from the app-image
& "$Env:JAVA_HOME\bin\jpackage.exe" --type msi \
--app-image target/jpackage/GraphDigitizer \
--dest target/jpackage-msi \
--name GraphDigitizer \
--icon build/icons/scatter-plot-256.ico \
--app-version 1.1 \
--win-dir-chooser --win-menu --win-shortcut
- Verify the produced MSI (automated smoke test):
# Run the included verification script (extracts the MSI, runs the bundled EXE briefly, and performs a silent install)
pwsh -NoProfile -ExecutionPolicy Bypass -File .\scripts\verify-msi.ps1 -TimeoutSeconds 30 -DoInstall
# Logs are written to: target/jpackage-msi/verify-msi.log, exe-run.log, exe-err.log, install.log
Where to find the artifacts:
-
App image:
target/jpackage/GraphDigitizer -
MSI installer:
target/jpackage-msi/GraphDigitizer-${project.version}.msi(example:target/jpackage-msi/GraphDigitizer-1.1.msi)
Notes & troubleshooting
-
If you see an error about WiX missing, install the WiX Toolset and add its
binto yourPATH.Use an Admin level PowerShell or Command Prompt and install through WinGet:
winget install WiXToolset.WiXCLI winget install WiXToolset.WiXAdditionalTools winget install WiXToolset.WiXToolset
-
If
jpackagefails with an "application destination directory already exists" error, thenativeprofile includes a cleanup exec that removestarget/jpackage/GraphDigitizerbefore packaging — runmvn -Pnative -DskipTests packageagain. -
The
pom.xmlcopies the shaded JAR totarget/jpackage-input/graph-digitizer.jarand platform JavaFX jars intotarget/jpackage-input/libautomatically when using thenativeprofile. -
If you want to run packaging on CI, run the packaging job on Windows-hosted runners for MSI outputs, and ensure WiX and a matching JDK are installed on the runner.
Advanced notes
-
You can override the installer type and icon via Maven properties:
-Djpackage.type=exe|msi|dmg|deb|rpmand-Dicon.win=path\to\icon.ico. -
To debug
jpackagearguments, run the manual two-step commands above and append--verboseto see detailed output. -
For signing the final EXE/MSI in CI, see
scripts/sign-windows.ps1which accepts a PFX and password (integrate with secure CI secrets).
If you'd like, I can add a small CI job example (GitHub Actions) to build and archive the MSI per-release.
For AppImage, DEB/RPM maintainer scripts, desktop integration, icon auto-selection, and cross-platform signing/notarization:
-
See
packaging/README.mdfor: AppImage recipe (appimage-builder.yml),.zsyncdelta update steps, Debianpostinst/prerm, RPM spec template, verification checklist, CI integration notes. -
Windows code signing:
scripts/sign-windows.ps1(SecureString support; integrate with CI secrets). -
macOS signing & notarization:
scripts/sign-macos.sh(codesign, submit, staple). -
Icon selection / generation:
scripts/select-icon.ps1(Windows) andscripts/create-mac-iconset.sh(macOS) produceselected-icon.properties/.icns.
Quick examples:
# Linux AppImage build (after jpackage app-image)
appimage-builder --recipe packaging/appimage-builder.yml
appimagetool --create-zsync GraphDigitizer-x86_64.AppImage # optional delta updates
# Windows signing (example)
pwsh scripts/sign-windows.ps1 -PfxPath certs/code_signing.pfx -PasswordEnvVar WINDOWS_CERT_PASS -Files (Get-ChildItem target -Filter *.exe).FullName
# macOS signing & notarization (example)
./scripts/sign-macos.sh GraphDigitizer.app "Developer ID Application: Your Company" TEAMID GraphDigitizer.dmg
JavaFX requires native libraries for each target OS. When packaging with
jlink/jpackage, include the JavaFX modules for the specific OS. When
building on CI for multiple OSes, build packages on each target OS
or use cross-compile tooling that provides platform-specific JavaFX
artifacts.
-
Install a JDK 21 with
jpackage(Adoptium OpenJDK or Liberica Full JDK). -
Build the jar and modules:
mvn clean package
jlink --module-path $JAVA_HOME/jmods:target/lib --add-modules java.base,java.desktop,javafx.controls,javafx.graphics --output runtime-mac
- Use
jpackageto make a.appbundle and optionally.dmg:
jpackage --type dmg --name GraphDigitizer --main-jar graph-digitizer-1.2.0.jar --main-class com.digitizer.ui.GraphDigitizerApp --runtime-image runtime-mac --icon build/icons/graphdigitizer.icns
-
Error "No JavaFX runtime found" typically means you haven't included the JavaFX modules for your OS; ensure
--module-pathcontains the JavaFX SDK modules. -
For Windows, use
--type msior--type exe. For.msiyou may needWiXinstalled on Windows for full packaging. -
Use
--verbosewithjpackagefor extra messages.
-
Core Business Logic: Place non-GUI code in the
corepackage. These classes can be tested and reused without JavaFX dependencies. -
Modularity: Each package has a specific responsibility:
-
core: Data models and algorithms -
image: Image I/O and processing -
io: File format handlers -
ui: User interface only
-
-
Testing: Unit tests in
src/test/javamirror the source structure. Test core logic independently of UI. -
Dependencies:
-
Core classes import only from Java standard library
-
Image/IO classes import from core and external libraries
-
UI classes import from core, image, and io packages
-
Example: Adding a new export format
-
Create a new exporter class in
com.digitizer.iopackage -
Implement export logic
-
Add unit tests in
src/test/java/com/digitizer/io/ -
Call the exporter from
MainWindowin the appropriate event handler
The UI is designed to be easily extensible. To add new controls:
-
Create a new panel class extending
javafx.scene.layout.RegionorVBox -
Initialize it in
MainWindow.initialize() -
Add it to the appropriate layout container
-
JavaFX 21.0.2: Modern UI framework
-
GSON 2.10.1: JSON serialization
-
Apache Commons CSV 1.10.0: CSV parsing and writing
-
SLF4J + Log4j2: Logging (console, rolling file, JSON, async option)
-
LMAX Disruptor: Enables Log4j2 asynchronous loggers
-
JUnit 4 & JUnit 5: Testing frameworks
Run all tests:
mvn test
Run specific test:
mvn test -Dtest=FileUtilsTest
The application manages three related coordinate systems and clarifies how they interact:
-
Image Pixel Coordinates: The image's natural pixel coordinate space (0..width-1, 0..height-1). The {@link com.digitizer.core.CoordinateTransformer} maps between numeric data values and these image pixel coordinates (this is the coordinate space used by the tracer and by the calibration anchors stored in {@link com.digitizer.core.CalibrationState}).
-
Canvas Coordinates: Pixel positions in the JavaFX Canvas where the image is rendered. The canvas may render the image at a scaled size (
displayScale) and with offsets (offsetX,offsetY) so UI drawing (snap lines, points, ticks) must convert image-pixel coordinates into canvas coordinates before drawing. -
Data Coordinates: Actual numeric values from the graph axes (e.g., 0.0..100.0). The transformer supports linear and logarithmic mappings between data coordinates and image pixels.
Note: Because the UI supports zooming (which changes displayScale) and fitting, the conversion helpers
in the UI layer perform image<->canvas conversions. This ensures points and tick marks remain visually in the
same place on the plotted graph when zoom/fitting changes are applied.
All core logic (coordinate transforms, color operations, file I/O) is intentionally GUI-free. This allows:
-
Unit testing without JavaFX/GUI headaches
-
Headless/command-line processing
-
Embedding in other applications
The application uses SLF4J with a Log4j2 backend (log4j2.xml). The configuration defines:
-
Console output with concise pattern
-
Rolling text file (
logs/graph-digitizer.log) with daily + size rollover (max 14 archives) -
Structured JSON events (
logs/graph-digitizer.json) newline-delimited for ingestion -
Package logger
com.digitizerat DEBUG and root at INFO
To enable async logging (reduces contention on the JavaFX UI thread), start the JVM with:
java -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -jar target/graph_digitizer_1.0-beta.jar
Maven/JavaFX run example:
mvn -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector javafx:run
Ensure the LMAX Disruptor dependency is present (already declared in pom.xml).
graph-digitizer.json is newline-delimited JSON (NDJSON). Example ingestion with jq:
jq -c '.' logs/graph-digitizer.json
Two example helper scripts are provided in scripts/ to parse and filter the structured JSON log:
-
PowerShell:
scripts/ingest-json-log.ps1(filter by level/logger) -
Python:
scripts/ingest_json_log.py(arguments--level/--logger)
Examples:
pwsh scripts/ingest-json-log.ps1 -Level ERROR
pwsh scripts/ingest-json-log.ps1 -Logger com.digitizer.ui
python scripts/ingest_json_log.py --level INFO --logger com.digitizer
The application initializes a session identifier via LoggingConfig.initializeMdc(...). Each log event includes MDC keys if referenced in patterns (add %X{session} to PatternLayout in log4j2.xml if you want it visible in the rolling text file). Current keys:
-
session: Unique per application run (epoch milliseconds) -
user: Reserved for future use (currently unset / null for desktop context)
Add a user id example:
LoggingConfig.initializeMdc(LoggingConfig.generateSessionId(), System.getProperty("user.name"));Update pattern example:
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %X{session} %logger - %msg%n"/>
At startup LoggingConfig.runEnvironmentChecks() logs:
-
Java version (
java.version) -
Whether async logging property is present
-
Creates
logs/directory if missing
Use the helper script to compress and prune older logs:
pwsh scripts/archive-logs.ps1 -Days 14
pwsh scripts/archive-logs.ps1 -DryRun
Creates logs/archive-YYYYMMDD-HHMMSS.zip and removes archived originals.
-
Change retention via
<DefaultRolloverStrategy max="X"/>inlog4j2.xml. -
Modify patterns with
<PatternLayout>; add%X{key}for MDC if needed. -
Remove JSON appender if structured logging not required.
Previous logback.xml has been removed due to a security review; Log4j2 >= 2.23.1 plus async option provides hardened, flexible logging.
Ensure Java 21 is installed and JAVA_HOME is set:
java -version
Verify the file is:
-
A valid image file
-
Readable by the current user
-
Not too large (tested up to 4K resolution)
Try:
mvn clean install
mvn javafx:run
Ensure Maven has internet access to download dependencies.
-
FXML-based UI layouts for better separation of concerns
-
Undo/redo stack
-
Project file format (.gdz) combining image + metadata
-
Keyboard shortcuts customization
-
Snap X values and guide lines (from Julia version)
-
Batch processing from command line
-
Plugin system for custom export formats
-
Precision zoom with circular magnifier overlay
Contributions are welcome! Please:
-
Write tests for new features
-
Follow the existing code style
-
Update documentation
-
Test on multiple platforms if possible
Licensed under the Apache License, Version 2.0. See LICENSE file for details.
For issues, questions, or suggestions, please open an issue on the repository.
This project is licensed under the Apache License 2.0; the copyright and
license headers are present in all source files. The generated Javadocs
are considered part of developer documentation and can be published as
project site pages (GitHub Pages, GitHub Actions mvn site deployments).
If you want a public API site, run:
mvn site
That will build documentation including Javadocs and test reports into
target/site suitable for hosting.