JFXHighlighter in Processing

Hello.

Has anyone used the JFoenix library with Processing. I am trying to make a text highlighter in a JavaFX TextArea. Since JavaFX doesn’t have one I tried using the JFoenix library without much success. After some research it seems that JFoenix and JavaFX API are incompatible?

This is the error i get.

java.lang.reflect.InaccessibleObjectException: Unable to make private com.sun.javafx.scene.text.TextLayout javafx.scene.text.Text.getTextLayout() accessible: module javafx.graphics does not “opens javafx.scene.text” to unnamed module @18be83e4

import processing.javafx.*;


import com.jfoenix.utils.*;
import com.jfoenix.controls.*;
import com.jfoenix.utils.JFXHighlighter;
import com.jfoenix.utils.JFXNodeUtils;
import com.jfoenix.utils.JFXUtilities;
import com.jfoenix.controls.JFXTextArea;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXTextField;
import java.util.*;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.scene.canvas.Canvas;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.Pane;
import javafx.application.Application;
import javafx.scene.layout.VBox;
import javafx.scene.text.TextFlow;


Pane pane;
Canvas canvas;
StackPane root;
Stage primaryStage;
  
JFXHighlighter highlighter = new JFXHighlighter();


void setup() {
  size(700, 600, FX2D);
  background(#FFFFFF);
  surface.setTitle("JavaFX C0ntrols");
  canvas = (Canvas)surface.getNative();
  root = (StackPane)canvas.getParent();
  pane = new Pane();
  root.getChildren().add(pane);
  JFXTextArea textArea = new JFXTextArea();
  textArea.setPromptText("Type some text here...");
  textArea.setPrefRowCount(6);

  // Search field
  JFXTextField searchField = new JFXTextField();
  searchField.setPromptText("Enter text to highlight");
  println("DEBUG");
  // Highlight button
  JFXButton highlightBtn = new JFXButton("Highlight");
  highlightBtn.setOnAction(e -> {
    String query = searchField.getText();
    if (query != null && !query.isEmpty()) {
      highlighter.clear(); // Clear previous highlights
      highlighter.highlight(textArea, query);
    }
  }
  );

  // Clear button
  JFXButton clearBtn = new JFXButton("Clear Highlights");
  clearBtn.setOnAction(e -> highlighter.clear());

  VBox vBoxMain = new VBox(10, textArea, searchField, highlightBtn, clearBtn);
  vBoxMain.setStyle("-fx-padding: 15;");

  pane.getChildren().add(vBoxMain);
}

Regards, Mike.

Link to the project folder.

Full Project

Did you mean JFXTextArea?

On my system (MacOS) the problem seems to be with JFXTextField. The following fails:

import com.jfoenix.controls.JFXTextField;
import javafx.scene.canvas.Canvas;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.Pane;

void setup() {
  size(350, 200, FX2D);
  Canvas canvas = (Canvas)surface.getNative();
  StackPane root = (StackPane)canvas.getParent();
  Pane pane = new Pane();

  JFXTextField textField = new JFXTextField();
  println(textField);

  pane.getChildren().add(textField);
  root.getChildren().add(pane);
}

The following will run provided I use the latest .jar file. However, it fails if the searchField is added to VBox.

import com.jfoenix.utils.*;
import com.jfoenix.controls.*;

import javafx.scene.canvas.Canvas;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.layout.Pane;

Pane pane;
Canvas canvas;
StackPane root;
JFXHighlighter highlighter;

void setup() {
  size(700, 600, FX2D);
  background(#FFFFFF);
  surface.setTitle("JFXHighlighter Demo");
  canvas = (Canvas)surface.getNative();
  root = (StackPane)canvas.getParent();
  pane = new Pane();

  highlighter = new JFXHighlighter();
  println("highlighter",highlighter);
  JFXTextArea textArea = new JFXTextArea();
  println("textArea =",textArea);
  textArea.setPromptText("Type some text here...");
  textArea.setPrefRowCount(6);  
  // Search field
  JFXTextField searchField = new JFXTextField();
  println("searchField = ",searchField);
  searchField.setPromptText("Enter text to highlight");
  // Highlight button  
  JFXButton highlightBtn = new JFXButton("Highlight");
  println("highlightBtn =",highlightBtn);  
  highlightBtn.setOnAction(e -> {
    println("highlight btn hit.");
    String query = searchField.getText();
    if (query != null && !query.isEmpty()) {
      highlighter.clear(); // Clear previous highlights
      highlighter.highlight(textArea, query);
    }
  }
  );
  // Clear button
  JFXButton clearBtn = new JFXButton("Clear Highlights");
  clearBtn.setOnAction(e -> {
    highlighter.clear();
    println("clear btn hit.");
  });

  VBox vBoxMain = new VBox(textArea,  highlightBtn,  clearBtn); //searchField,
  vBoxMain.setStyle("-fx-padding: 15;");
  pane.getChildren().add(vBoxMain); 
  root.getChildren().add(pane);
}

The fix is supposedly to add:

–add-opens java.base/java.lang.reflect=ALL-UNNAMED

which may go in a gradle file. I tried adding it to Preferences.txt but it didn’t seem to help.

Output:

Thanks @svan .

adding it like this to preferences.txt fixed the issue.

run.options=-–add-opens=java.base/java.lang.reflect=ALL-UNNAMED

There were five other opens/exports that had to be added as well.

I’m glad that you got it to working. What operating system are you using? I can’t get it to run on my macOS system; Processing keeps overwriting my Preferences.txt file and deleting the above line that I added. I did have the Processing.app closed when I made the changes. Any way that you could update your above link to a runnable demo? What are the other additions that you had to make to Preferences.txt and did you add the lines at the top of the file or someplace else? Thanks for making us aware of this interface.

I noticed if you enter incorrect data Processing reverts the changes. It also printed an error in the console saying which line was incorrect.

Windows10.

You do have to restart IDE for changes to take effect.

Preference File

see line 87.

Project

Hello @swp791,

It took interest!

Environment:

  • Windows 10
  • Processing 4.5.2
  • jfoenix-9.0.10.jar was added to sketch (drag and drop).

Your code ran without error adding this to Preferences:

--add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=javafx.graphics/javafx.scene.text=ALL-UNNAMED --add-opens=javafx.graphics/javafx.scene=ALL-UNNAMED --add-opens=javafx.controls/javafx.scene.control.skin=ALL-UNNAMED --add-exports=javafx.controls/com.sun.javafx.scene.control=ALL-UNNAMED

ChatGPT was used to analyze the initial errors and direct me to a solution.

ChatGPT Reference:

:)

Yes! That’s about it. Its good to know i can edit those preferences from the IDE now.

2 Likes