FXTrayIcon

repository·main·Indexed 18 days ago

https://github.com/dustinkredmond/fxtrayicon

A JavaFX library that simplifies adding system tray icons to applications by abstracting AWT and Swing. It allows developers to manage tray icons, context menus, and notifications using JavaFX classes. Features include a fluent Builder API, support for animated icons, system tray notifications with various severity levels, and cross-platform support for Windows, macOS, and Linux.

Tokens
3.3K
Snippets
11
Records
14
Agent score
13%

What's inside FXTrayIcon

  1. Install FXTrayIcon via Maven, Gradle, or Groovy

    main

    FXTrayIcon is available on Maven Central. Choose the dependency format that matches your build system.

    Maven

    Add this to your pom.xml:

    Gradle

    Add this to your Gradle build file:

    Groovy

    Use @Grapes for Groovy scripts:

    <!-- Maven -->
    <dependency>
      <groupId>com.dustinredmond.fxtrayicon</groupId>
      <artifactId>FXTrayIcon</artifactId>
      <version><!--See Below --></version>
    </dependency>
    
    <!-- Gradle -->
    compile group: 'com.dustinredmond.fxtrayicon', name: 'FXTrayIcon', version: '<see below>'
    
    <!-- Groovy -->
    @Grapes(
      @Grab(group='com.dustinredmond.fxtrayicon', module='FXTrayIcon', version='<see below>')
    )
  2. Animate the Tray Icon

    main

    You can animate the tray icon by providing a sequence of images (frames). This is useful for indicating background processing.

    1. Prepare the frames

    Create a LinkedList<File> or LinkedList<Image> containing the frames in sequence. It is recommended to sort files by name if loading from a directory.

    File[] files = new File("path/to/my/imageFiles").listFiles();
    LinkedList<File> fileList = new LinkedList<>(Arrays.asList(files));
    fileList.sort(Comparator.comparing(File::getName));

    2. Apply the animation

    Use the Builder or call .newAnimation() on an existing instance. The integer parameter specifies the frame duration in milliseconds.

    Via Builder:

    trayIcon = new FXTrayIcon.Builder(primaryStage, iconFile)
        .animate(fileList, 75)
        .addExitMenuItem("Exit", e -> Main.stopRunning())
        .show()
        .build();

    After instantiation:

    trayIcon.newAnimation(fileList, 75);

    3. Control the animation

    Use the following methods to manage playback:

    • play(): Start animation.
    • playFromStart(): Restart animation.
    • stop(): Stop animation.
    • pause(): Pause animation.
    • pauseResume(): Toggle pause/resume.
    • stopReset(): Stop and reset.
    • resetIcon(): Reset to the original static icon.

    4. Check animation state

    • isRunning()
    • isPaused()
    • isStopped()
    • getTimeline(): Access the underlying animation timeline.
    File[]  files = new File("path/to/my/imageFiles").listFiles();
    LinkedList<File> fileList = new LinkedList<>(Arrays.asList(files));
    fileList.sort(Comparator.comparing(File::getName));
    
    trayIcon = new FXTrayIcon.Builder(primaryStage, iconFile)
        .animate(fileList, 75)
        .addExitMenuItem("Exit", e -> Main.stopRunning())
        .show()
        .build();
  3. Basic Usage of FXTrayIcon

    main

    To add a tray icon to your JavaFX application, instantiate FXTrayIcon with your application's main Stage and the resource URL for your icon image, then call .show().

    // Pass in the app's main stage, and path to the icon image
    FXTrayIcon icon = new FXTrayIcon(stage, getClass().getResource("someImageFile.png"));
    icon.show();
    FXTrayIcon icon = new FXTrayIcon(stage, getClass().getResource("someImageFile.png"));
    icon.show();
  4. Add an Exit menu item

    main

    The .addExitMenuItem(...) method adds a special item that is always placed at the bottom of the menu, regardless of when it is called in the builder chain. Clicking this item closes the application.

    Options:

    • .addExitMenuItem(): Uses the default label.
    • .addExitMenuItem(String label): Uses a custom label.
    • .addExitMenuItem(String label, EventHandler<ActionEvent> handler): Uses a custom label and a custom exit logic handler.
    // Default exit item
    new FXTrayIcon.Builder(stage, icon).addExitMenuItem().build();
    
    // Custom label exit item
    new FXTrayIcon.Builder(stage, icon).addExitMenuItem("Exit App").build();
    
    // Custom logic exit item
    new FXTrayIcon.Builder(stage, icon).addExitMenuItem("Quit", e -> myExitMethod()).build();
  5. Use the FXTrayIcon Builder

    main

    The FXTrayIcon.Builder provides a fluent API to configure the icon, add menu items, and set exit actions in a single chain.

    FXTrayIcon icon = new FXTrayIcon.Builder(stage, iconURL)
        .menuItem("Menu 1", e -> myMethod())
        .addExitItem()
        .show()
        .build();
    FXTrayIcon icon = new FXTrayIcon.Builder(stage, iconURL).menuItem("Menu 1", e-> myMethod()).addExitItem().show().build();
  6. Show Tray Notifications

    main

    FXTrayIcon provides several methods to display system tray notifications. Some methods use the application's tray icon, while others use standard severity icons (Info, Warning, Error).

    • showMessage(String caption, String content): Uses the application's tray icon.
    • showMessage(String content): Uses the application's tray icon.
    • showInfoMessage(String caption, String content): Uses an info icon.
    • showInfoMessage(String content): Uses an info icon.
    • showWarnMessage(String caption, String content): Uses a warning icon.
    • showWarnMessage(String content): Uses a warning icon.
    • showErrorMessage(String caption, String content): Uses an error icon.
    • showErrorMessage(String content): Uses an error icon.
  7. Add submenus and CheckMenuItems

    main

    You can create branched submenus in two ways:

    1. Pre-built Menu: Create a javafx.scene.control.Menu object, add items to it, and pass it to .menu(Menu menu).
    2. Dynamic Submenu: Use .menu(String label, MenuItem... items) to create a submenu and its items in one call.

    You can also include CheckMenuItem objects using .checkMenuItem(CheckMenuItem item) or .checkMenuItem(String label, EventHandler<ActionEvent> handler).

    // Pre-built Menu with CheckMenuItem
    Menu menu = new Menu("My Sub Menu");
    MenuItem myMenuItem1 = new MenuItem();
    myMenuItem1.setOnAction(e -> myMenuMethod1());
    
    CheckMenuItem myCheckMenuItem = new CheckMenuItem();
    myCheckMenuItem.setOnAction(e -> myCheckMenuMethod());
    
    menu.getItems().addAll(myMenuItem1, myCheckMenuItem);
    
    new FXTrayIcon.Builder(stage, icon)
        .menu(menu)
        .build();
    
    // Dynamic Submenu
    new FXTrayIcon.Builder(stage, icon)
        .menu("My Sub Menu", menuItem1, menuItem2)
        .build();
  8. Access the underlying AWT TrayIcon

    main

    If you need to access the underlying java.awt.TrayIcon object, you can do so in two ways:

    1. Subclassing: Extend FXTrayIcon and call the protected getTrayIcon() method.
    2. Instance Access: Call getRestricted() on an instantiated FXTrayIcon to gain access to the TrayIcon object.
  9. Configure Icon Size

    main

    While FXTrayIcon automatically selects the optimal size for the operating system, you can manually override it using .setIconSize() in the Builder or on an existing instance.

    Recommended optimal sizes:

    • Linux: 22 x 22
    • MacOS: 22 x 22
    • Windows: 16 x 16

    Usage:

    // Using Builder
    .setIconSize(width, height);
    .setIconSize(oneValueWH);
    
    // After instantiation
    trayIcon.setIconSize(16, 16);
    .setIconSize(width, height);
    .setIconSize(oneValueWH);
  10. Configure tray icon appearance and behavior

    main

    The Builder provides several methods to customize the tray icon's interaction and metadata:

    • .separator(): Adds a visual separator line in the menu at the current position in the builder chain.
    • .tooltip(String text): Sets the tooltip displayed when hovering over the icon.
    • .onAction(EventHandler<ActionEvent> handler): Defines the event triggered by clicking the icon. Note: Behavior varies by OS (Windows: left-click; Mac: simultaneous left and right click).
    • .applicationTitle(String title): Sets a custom application title.
    • .addTitleItem(boolean value): If true, adds a TitleItem at the top of the menu. This is a special MenuItem that, when clicked, brings the associated primaryStage into view.
    new FXTrayIcon.Builder(stage, icon)
        .menuItem("Menu 1", e -> action())
        .separator()
        .menuItem("Menu 2", e -> action())
        .tooltip("My Tooltip")
        .onAction(e -> myMethod())
        .applicationTitle("My App")
        .addTitleItem(true)
        .build();
  11. Show the tray icon immediately

    main

    By default, you must call .show() on the FXTrayIcon instance after building it. To build and display the icon in a single fluent statement, append .show() to your builder chain before calling .build().

    new FXTrayIcon.Builder(stage, icon)
        .menuItem("Menu 1", e -> action())
        .addExitMenuItem()
        .show()
        .build();
  12. Add menu items to FXTrayIcon

    main

    You can add menu items to your tray icon using two approaches: dynamically (passing a label and an event handler) or by using pre-built JavaFX MenuItem objects.

    Dynamic Menu Items

    Use .menuItem(String label, EventHandler<ActionEvent> handler) to create items on the fly.

    Pre-built Menu Items

    Use .menuItem(MenuItem item) for a single item or .menuItems(MenuItem... items) for multiple items.

    // Dynamic menu items
    new FXTrayIcon.Builder(stage, icon)
        .menuItem("My Menu 1", e -> myMenuMethod1())
        .menuItem("My Menu 2", e -> myMenuMethod2())
        .build();
    
    // Pre-built menu items
    MenuItem myMenuItem1 = new MenuItem();
    myMenuItem1.setOnAction(e -> myMenuMethod1());
    
    MenuItem myMenuItem2 = new MenuItem();
    myMenuItem2.setOnAction(e -> myMenuMethod2());
    
    new FXTrayIcon.Builder(stage, icon)
        .menuItems(myMenuItem1, myMenuItem2)
        .build();