MaxAxeHax
MaxAxeHax

Reputation: 444

Tracking unsaved changes in Java Swing application

My question

What would be a good way for notifying the "top-level" model (the one that represents the whole application, but without knowing the details of every "child" model it is composed of) whenever any little change has happened to any of the "child" models?

Context for the question

I'm buliding a medium Java Swing application. Roughly speaking, it "models" a calculation, allowing the inputs and parameters to be tweaked. It updates the results and intermediate steps of the calculation in real time. This allows one to analyze how input changes reflect overall.

The application can save and load this "calculation" using the file system. I want to know how to track if the application's "model" has any unsaved changes so that I can:

  1. Prompt to save before closing if unsaved changes present
  2. Directly close if no unsaved changes present
  3. Prompt to save when new file is opened (by design, there can only be 1 open file)

I've built this application following a MVC architecture. This means that every one of my view (Swing) elements get notifications (via Observer.update() ) whenever a corresponding model object changes, and so the view elements get updated selectively instead of having to render all of the view for a tiny change that doesn't affect everything.

The views and models are built hierarchically, so a model contains other models and a view contains other views. "Parent" views create their "child" views by assigning to them "child" models that they get from their own "parent" model.

What I consider sub-optimal solutions and why

Having the main view observe every single little model

I don't what to add the main view as a listener/observer to every single model in the application, because there are really a lot of model objects, and the main view would thus get an incredibly high noise-to-signal ratio (the calculation the models perform have many steps, which each trigger an update, and I only need to know something has changed once and not every single time).

Having a reference to the main model in every little model to notify it on changes

I don't want every single model object to have a reference to the main model, because these seems to me to be against basic software design principles.

Every model has a parent reference. On change, the parent is notified

If a child changes, it tells its parent; this propagates up until the "main" model object gets notified, which can change its state to reflect there are unsaved changes. When it saves, it sets this flag back. Seems a quasi-ideal solution except that I don't like the fact that each child model would need a reference to its parent model - the semantics of the composition or "has-a"-relation seem to be bent backwards if I do this.

Upvotes: 3

Views: 448

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

You have at least two choices

You could...

Have the parent model check each child model (and each child model checks it's children) and look for any (or the first) model that has changed

This is good if you only want to know the state at some given moment (like before exiting the application). It's relatively inexpensive as you can control when to perform the check manually and doesn't use up a lot of additional resources in maintaining callbacks and processing events notifications

You could...

Have each child model trigger an event when it's changed, which the parent model (right at the top) can use to track changes.

Having each child model trigger an event is good if you want to maintain real time observations of the model, but it is some what expensive, as each model might be observed by multiple observers, so notifying each of them could be expensive. You would also need to chain the events, so the child model right at the bottom would notify it's parent, which would notify it's parent, so on and so fourth until it reaches the top parent model...

Upvotes: 1

Related Questions