How to listen to visible changes to the JavaFX SceneGraph for specific node

crusam

We created a small painting application in JavaFX. A new requirement arose, where we have to warn the user, that he made changes, which are not yet persisted and asking him, if the user might like to save first before closing.

Sample Snapshot:

Canvas Image

Unfortunately there are a lot of different Nodes, and Nodes can be changed in many ways, like for example a Polygon point can move. The Node itself can be dragged. They can be rotated and many more. So before firing a zillion events for every possible change of a Node object to the canvas I`d like to ask, if anyone might have an idea on how to simplify this approach. I am curious, if there are any listeners, that I can listen to any changes of the canvas object within the scene graph of JavaFX.

Especially since I just want to know if anything has changed and not really need to know the specific change.

Moreover, I also do not want to get every single event, like a simple select, which causes a border to be shown around the selected node (like shown on the image), which does not necessary mean, that the user has to save his application before leaving.

Anyone have an idea? Or do I really need to fire Events for every single change within a Node?

James_D

Benjamin's answer is probably the best one here: you should use an underlying model, and that model can easily check if relevant state has changed. At some point in the development of your application, you will come to the point where you realize this is the correct way to do things. It seems like you have reached that point.

However, if you want to delay the inevitable redesign of your application a little further (and make it a bit more painful when you do get to that point ;) ), here's another approach you might consider.

Obviously, you have some kind of Pane that is holding the objects that are being painted. The user must be creating those objects and you're adding them to the pane at some point. Just create a method that handles that addition, and registers an invalidation listener with the properties of interest when you do. The structure will look something like this:

private final ReadOnlyBooleanWrapper unsavedChanges = 
    new ReadOnlyBooleanWrapper(this, "unsavedChanged", false);

private final ChangeListener<Object> unsavedChangeListener = 
    (obs, oldValue, newValue) -> unsavedChanges.set(true);

private Pane drawingPane ;

// ...

Button saveButton = new Button("Save");
saveButton.disableProperty().bind(unsavedChanges.not());

// ...
@SafeVarArgs
private final <T extends Node> void addNodeToDrawingPane(
        T node, Function<T, ObservableValue<?>>... properties) {

    Stream.of(properties).forEach(
        property -> property.apply(node).addListener(unsavedChangeListener));
    drawingPane.getChildren().add(node);
}

Now you can do things like

    Rectangle rect = new Rectangle();

    addNodeToDrawingPane(rect, 
            Rectangle::xProperty, Rectangle::yProperty, 
            Rectangle::widthProperty, Rectangle::heightProperty);

and

    Text text = new Text();
    addNodeToDrawingPane(text, 
            Text::xProperty, Text::yProperty, Text::textProperty);

I.e. you just specify the properties to observe when you add the new node. You can create a remove method which removes the listener too. The amount of extra code on top of what you already have is pretty minimal, as (probably, I haven't seen your code) is the refactoring.

Again, you should really have a separate view model, etc. I wanted to post this to show that @kleopatra's first comment on the question ("Listen for invalidation of relevant state") doesn't necessarily involve a lot of work if you approach it in the right way. At first, I thought this approach was incompatible with @Tomas Mikula's mention of undo/redo functionality, but you may even be able to use this approach as a basis for that too.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

JavaFX: Listen for position changes of a node

From Dev

How to focus a specific node when selected tab changes in JavaFX?

From Dev

JavaFX TabPane: How to listen to selection changes

From Dev

JavaFX - Listen to Changes in List

From Dev

Javafx listen for Control changes in a Panel

From Dev

Javafx listen for Control changes in a Panel

From Dev

Working on the JavaFX SceneGraph

From Dev

Working on the JavaFX SceneGraph

From Java

How to listen for specific property changes in Redux store after an action is dispatched

From Java

How to listen for 'props' changes

From Dev

JavaFX - How to delete a specific Node from an AnchorPane

From Dev

How to listen changes in routing Angular?

From Dev

JavaFX apply specific order to visible columns of TableView

From Dev

How can i listen MySQL database changes in real time with Node.js or PHP

From Dev

How to get node bounds according to its specific ancestor in JavaFX 8?

From Dev

JavaFX SortedList: listen the list changes and the list items updated event

From Dev

How to listen to a specific button with jquery

From Java

How to listen state changes in react.js?

From Dev

How to listen to changes in the rotation of the camera in A-Frame?

From Dev

How to listen to changes on 'File Name' TextField in JFileChooser?

From Dev

How to listen for changes to a img title attribute?

From Dev

how to listen for SQLite database changes in android

From Dev

How to listen to mongoDB changes using C#

From Dev

How to listen mysql database changes in Android

From Dev

How to listen to changes in Firebase database collection?

From Dev

React Native - How to listen to permissions changes?

From Dev

How to listen to changes on 'File Name' TextField in JFileChooser?

From Dev

How to create custom directive to listen to input changes

From Dev

Listen to changes on childs with keys within specific range only?

Related Related

  1. 1

    JavaFX: Listen for position changes of a node

  2. 2

    How to focus a specific node when selected tab changes in JavaFX?

  3. 3

    JavaFX TabPane: How to listen to selection changes

  4. 4

    JavaFX - Listen to Changes in List

  5. 5

    Javafx listen for Control changes in a Panel

  6. 6

    Javafx listen for Control changes in a Panel

  7. 7

    Working on the JavaFX SceneGraph

  8. 8

    Working on the JavaFX SceneGraph

  9. 9

    How to listen for specific property changes in Redux store after an action is dispatched

  10. 10

    How to listen for 'props' changes

  11. 11

    JavaFX - How to delete a specific Node from an AnchorPane

  12. 12

    How to listen changes in routing Angular?

  13. 13

    JavaFX apply specific order to visible columns of TableView

  14. 14

    How can i listen MySQL database changes in real time with Node.js or PHP

  15. 15

    How to get node bounds according to its specific ancestor in JavaFX 8?

  16. 16

    JavaFX SortedList: listen the list changes and the list items updated event

  17. 17

    How to listen to a specific button with jquery

  18. 18

    How to listen state changes in react.js?

  19. 19

    How to listen to changes in the rotation of the camera in A-Frame?

  20. 20

    How to listen to changes on 'File Name' TextField in JFileChooser?

  21. 21

    How to listen for changes to a img title attribute?

  22. 22

    how to listen for SQLite database changes in android

  23. 23

    How to listen to mongoDB changes using C#

  24. 24

    How to listen mysql database changes in Android

  25. 25

    How to listen to changes in Firebase database collection?

  26. 26

    React Native - How to listen to permissions changes?

  27. 27

    How to listen to changes on 'File Name' TextField in JFileChooser?

  28. 28

    How to create custom directive to listen to input changes

  29. 29

    Listen to changes on childs with keys within specific range only?

HotTag

Archive