'How do I dynamically update a java property when the value of another property within the same class is updated
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);
}
Solution 1:[1]
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);
}
}
}
Solution 2:[2]
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/
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | braian azcune |
| Solution 2 | swapyonubuntu |
