Interacto JavaFX

The JavaFX implementation of the Interacto library

License

License

Categories

Categories

JavaFX User Interface
GroupId

GroupId

io.github.interacto
ArtifactId

ArtifactId

interacto-javafx
Last Version

Last Version

4.3.1
Release Date

Release Date

Type

Type

jar
Description

Description

Interacto JavaFX
The JavaFX implementation of the Interacto library
Project URL

Project URL

https://interacto.github.io
Project Organization

Project Organization

DiverSE research group
Source Code Management

Source Code Management

https://github.com/interacto/interacto-javafx

Download interacto-javafx

How to add to project

<!-- https://jarcasting.com/artifacts/io.github.interacto/interacto-javafx/ -->
<dependency>
    <groupId>io.github.interacto</groupId>
    <artifactId>interacto-javafx</artifactId>
    <version>4.3.1</version>
</dependency>
// https://jarcasting.com/artifacts/io.github.interacto/interacto-javafx/
implementation 'io.github.interacto:interacto-javafx:4.3.1'
// https://jarcasting.com/artifacts/io.github.interacto/interacto-javafx/
implementation ("io.github.interacto:interacto-javafx:4.3.1")
'io.github.interacto:interacto-javafx:jar:4.3.1'
<dependency org="io.github.interacto" name="interacto-javafx" rev="4.3.1">
  <artifact name="interacto-javafx" type="jar" />
</dependency>
@Grapes(
@Grab(group='io.github.interacto', module='interacto-javafx', version='4.3.1')
)
libraryDependencies += "io.github.interacto" % "interacto-javafx" % "4.3.1"
[io.github.interacto/interacto-javafx "4.3.1"]

Dependencies

compile (1)

Group / Artifact Type Version
io.github.interacto : interacto-java-api jar 4.3.1

provided (5)

Group / Artifact Type Version
org.openjfx : javafx-base jar 11.0.2
org.openjfx : javafx-graphics jar 11.0.2
org.openjfx : javafx-controls jar 11.0.2
org.openjfx : javafx-fxml jar 11.0.2
org.openjfx : javafx-swing jar 11.0.2

test (7)

Group / Artifact Type Version
org.junit.jupiter : junit-jupiter-engine jar 5.6.0
org.junit.jupiter : junit-jupiter-params jar 5.6.0
org.testfx : testfx-core jar 4.0.16-alpha
org.testfx : testfx-junit5 jar 4.0.16-alpha
org.mockito : mockito-junit-jupiter jar 3.3.0
org.testfx : openjfx-monocle jar jdk-11+26
io.github.interacto : interacto-javafx-test jar 4.2

Project Modules

There are no modules declared in this project.

Jenkins Jenkins Coverage GitHub Maven Central java

Interacto JavaFX

The JavaFX binding of the Interacto library.

Interacto is a UI library that eases the processing of user interface events. A developer uses the Interacto fluent API to configure how a selected user interaction is transformed into a (undoable) command.

Examples

Following a serie of examples. For each example, the first code chunk is the JavaFX code that uses standard UI events. The second is the equivalent Interacto code.

  • A very basic example. I want to undo the latest command by clicking on the undo button.
undoButton.setOnAction(evt -> {
    // do the undo job here
});
buttonBinder()
    .toProduce(Undo::new)
    .on(undoButton)
    .bind();

What differences?

You do not use UI event and listeners but pre-defined user interactions (provided by buttonBinder here). In this case, the benefits is not direct as a button interaction is quite simple (it involves a single UI event).

You define commands (the Undo class here): classes that will do the job, and you can also add undo/redo features in your commands. Defining commands as classes have several benefits here: your UI processing code is less complex as the command bahevior is defined in a specific class; you can easily make your commands undoable; you can access and manage the history of executed commands; you factorise your code as commands may be executed in several places in your code.

  • I want to delete a selected object by pressing on the key DELETE.
canvas.addEventHandler(KeyEvent.KEY_TYPED, evt -> {
    if(evt.getCode() == KeyCode.DELETE) {
        // do the deletion job here
    }
});
shortcutBinder()
    .toProduce(() -> new DeleteShapes(canvas.getSelection()))
    .on(canvas)
    .with(KeyCode.DELETE)
    .bind();

Instead of having an if statement checking the key, you can use the routine with that will do the job for you. So it reduces the cyclomatic complexity.

  • I want to drag-and-drop (DnD) the selected color of a color picker onto an object to change its color.

A much more complex example in vanilla JavaFX.

lineCol.addEventHandler(MouseEvent.MOUSE_DRAGGED, evt -> {
    lineCol.getScene().setCursor(new ColorCursor(lineCol.getValue()));
});

lineCol.addEventHandler(MouseEvent.MOUSE_RELEASED, evt -> {
    if(evt.getPickResult().getIntersectedNode() instanceof Shape) {
        // do the command here
    }
    lineCol.getScene().setCursor(Cursor.DEFAULT);
});

With this example, the Interacto code is not less verbose but much more direct and avoids the use of spaghetti of callbacks.

nodeBinder()
    .usingInteraction(DnD::new)
    .toProduce(i -> new ChangeColour(lineCol.getValue(), null))
    .on(colorPicker)
    .first(i -> lineCol.getScene().setCursor(new ColorCursor(lineCol.getValue())))
    .then((i, c) -> i.getTgtObject().map(view -> (MyShape) view.getUserData()).ifPresent(sh -> c.setShape(sh)))
    .when(i -> i.getTgtObject().orElse(null) instanceof Shape)
    .endOrCancel(i -> colorPicker.getScene().setCursor(Cursor.DEFAULT))
    .bind();

with explanations:

nodeBinder()
    // I want to use a built-in DnD interaction
    .usingInteraction(DnD::new)
    // to produce as output a command that will change the color of the targeted object
    .toProduce(i -> new ChangeColour(lineCol.getValue(), null))
    // the DnD operates on the color picker
    .on(colorPicker)
    // at the beginning of the DnD I change the cursor of the app
    .first(i -> lineCol.getScene().setCursor(new ColorCursor(lineCol.getValue())))
    // on each update of the ongoing DnD I look at the current targeted object
    .then((i, c) -> i.getTgtObject().map(view -> (MyShape) view.getUserData()).ifPresent(sh -> c.setShape(sh)))
    // 'When' is a predicate that constraints the execution of the command.
    // I want to change the color of a Shape object only
    .when(i -> i.getTgtObject().orElse(null) instanceof Shape)
    // when the DnD ends or is cancelled, I set the default cursor
    .endOrCancel(i -> colorPicker.getScene().setCursor(Cursor.DEFAULT))
    // I build the widget binding
    .bind();
io.github.interacto

Interacto

Versions

Version
4.3.1
4.3.0
4.2
4.1
4.0