Home > Software engineering >  How do I dynamically update a java property when the value of another property within the same class
How do I dynamically update a java property when the value of another property within the same class

Time:04-08

I have a Java class called Project. It has three properties (among others): goal, amountRaised and percentageRaised.

goal is the amount of money the project aims to raise; amountRaised is as the name implies amount raised so far; and percentageRaised is the percentage of money raised relative to the goal.

I want percentageRaised to be updated anytime either goal or amountRaised changes.

My question is, if I declare a setter method (private) for percentageRaised, is it going to be calculated automatically or do I need to call it somewhere?

Alternatively, would it be bad practice to add the logic on initialisation like so:

public class Project {

    @JsonProperty
    private String id;

    @NotBlank(message = "Please specify the amount of money you intend to raise")
    @JsonProperty
    private double goal;

    @JsonProperty
    private double amountRaised = 0;

    @JsonProperty
    private int percentageRaised = (int) ((amountRaised/goal) * 100);
}

CodePudding user response:

the easiest way is to execute a calculation method in the setter of both attributes.

public class Project {

    @JsonProperty
    private String id;

    @NotBlank(message = "Please specify the amount of money you intend to raise")
    @JsonProperty
    private double goal;

    @JsonProperty
    private double amountRaised = 0;

    @JsonProperty
    private int percentageRaised = (int) ((amountRaised/goal) * 100);

    public void setGoal(double goal) {
        this.goal = goal;
        this.calculatePercentageRaised();
    }

    public void setAmountRaised(double amountRaised) {
        this.amountRaised = amountRaised;
        this.calculatePercentageRaised();
    }
    
    private void calculatePercentageRaised() {
      //check not null
      if (amountRaised!=null && goal!=null && goal != 0) {
        this.percentageRaised = (int) ((amountRaised/goal) * 100);
      }
    }
}

CodePudding user response:

This can be achieved with help of basic java beans PropertyChangeListener

package p1;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;

public class Project implements PropertyChangeListener, Serializable {

    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
    private String id;
    private double goal = 1;
    private double amountRaised = 0;
    private double percentageRaised = 0;

    public Project() {
        pcs.addPropertyChangeListener(this);
    }

    public static void main(String[] args) {
        Project project = new Project();
        project.setAmountRaised(20);
        System.out.printf("\n1: now, amountraised= is %f, goal is %f, percent is %f",
            project.amountRaised, project.goal, project.percentageRaised);
        project.setGoal(50);

        System.out.printf("\n2: now, amountraised= is %f, goal is %f, percent is %f",
            project.amountRaised, project.goal, project.percentageRaised);
        project.setGoal(100);
        System.out.printf("\n3: now, amountraised= is %f, goal is %f, percent is %f",
            project.amountRaised, project.goal, project.percentageRaised);
    }

    public void setGoal(double goal) {
        var old = this.goal;
        this.goal = goal;
        pcs.firePropertyChange("goal", old, goal);
    }

    public void setAmountRaised(double amountRaised) {
        var old = this.amountRaised;
        this.amountRaised = amountRaised;
        pcs.firePropertyChange("amountRaised", old, amountRaised);
    }

    public void updatePercentageRaised() {
        this.percentageRaised = ((amountRaised / goal) * 100);
        ;
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt) {
        updatePercentageRaised();
    }
}

Output:

1: now, amountraised= is 20.000000, goal is 1.000000, percent is 2000.000000
2: now, amountraised= is 20.000000, goal is 50.000000, percent is 40.000000
3: now, amountraised= is 20.000000, goal is 100.000000, percent is 20.000000

Ref: https://docs.oracle.com/javase/tutorial/javabeans/writing/properties.html.

https://kodejava.org/how-do-i-listen-for-beans-property-change-event/

CodePudding user response:

This is a simple approach for you.

You don't have to declare a field to record the percentageRaised value:

   // remove it
   @JsonProperty
   private int percentageRaised 

just calculate it when you need it, like this:

    @JsonGetter("percentageRaised")
    public int getPercentageRaised() {
        return (int) ((amountRaised/goal) * 100);
    }

Thus, you don't need to care about dynamic update issue anymore. The percentageRaised is always latest.

  •  Tags:  
  • java
  • Related