In order to understand how JFace databindings is working, I have a model object with two properties. Changing one property should set the other to the same value:
public class Model {
private double x;
private double y;
private PropertyChangeSupport changeSupport = new PropertyChangeSupport(this);
public void addPropertyChangeListener(String propertyName,
PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
public void setX(double x) {
propertyChangeSupport.firePropertyChange("x", this.x, this.x = x);
}
public double getX() {
return x;
}
public void setY(double y) {
propertyChangeSupport.firePropertyChange("y", y, this.y = y);
setX(y);
}
public double y() {
return y;
}
}
Now in a separate class I define two Text widgets, xText and yText, which are bound to this object like this:
DataBindingContext bindingContext = new DataBindingContext();
bindingContext.bindValue(WidgetProperties.text(SWT.Modify).observe(xText),
BeanProperties.value(HumidityScanParameters.class,"x").observe(getModel()));
bindingContext.bindValue(WidgetProperties.text(SWT.Modify).observe(yText),
BeanProperties.value(HumidityScanParameters.class, "y").observe(getModel()));
I have found that if I change the text in yText, then the setter is automatically called as expected, and this sets both y and x in the model. However, xText is not updated. Why is this? Shouldn't the firePropertyChange() call arrange for the Text to be updated?
Thanks,
Graham.
The compiler was optimising away the initial value of this.x and this.y, which led the PropertyChangeSupport instance to discard the change notification. It didn't think anything had changed. If I introduce a temporary variable like this:
public void setX(double x) {
double oldValue = this.x;
this.x = x;
propertyChangeSupport.firePropertyChange("x", oldValue, x);
}
then the notifications occur as I might expect.
I guess it's because you put this.x to your event before haveing it updated properly.
Try this:
public void setX(double x) {
this.x = x; // update the model!
propertyChangeSupport.firePropertyChange("x", this.x, x);
}
(see comments ;-) )
Related
I am trying to make a videogame that is similar to "Turing Complete". In this game you are supposed to connect circuit pieces to create a computer by the end. So I have a question on inheritance. I have a class called "Circuitware" and every object extends this as follows
public Circuitware implements connectable {
protected int x;
protected int y;
protected int allowedConnetions;
protected Ciruitware[] connections;
private int totalConnections;
public Circuitware(int x, int y, int allowedConnections, Circuitware[] connections) {
this.x = x;
this.y = y;
this.allowedConnections = allowedConnections;
this.connections = new Array[allowedConnections];
for (Object O: connections) {
if (O != null) {
this.totalConnections += 1;
}
}
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public<T> void addConnection(T connection) {
if (this.totalConnections<this.allowedConnections) {
this.connections.add(connection);
}
}
}
Now an example of a subclass is
public class LogicGate extends Circuitware {
String type;
public LogicGate(int x, int y, int allowedConnections, Circuitware[] connections, String type) {
super(x, y, allowedConnections, connections);
this.type = type;
}
public boolean output() {
//Depending on the gate and input we output things
}
}
Now the thing is that the number of allowed connections depends on the type of the circuit, for example logic gates in my game can have 1 connection if it is an NOT gate, 2 connections if it is an AND, XOR, NOR gates or 3 connections if it is and extended OR, extended AND gates, where are switches can only have 0. Is there are better way of doing this?
I also need help understanding that if I have an array of type Circuitware can I add objects from its subclasses? Because the output of logic gates and inputs of other logic gates while they can be inputs to clocks.
Would it be better, design-wise, if I got rid of the "Circuitware" class altogether? But then wouldn't that make connections between different classes harder?
Lets say I have two classes. Pair:
public class Pair<X, Y> {
public X x;
public Y y;
public Pair(X x , Y y) {
this.x = x;
this.y = y;
}
}
and the class Triple:
public class Triple<X, Y, Z> {
public X x;
public Y y;
public Z z;
public Triple(X x , Y y, Z z) {
this.x = x;
this.y = y;
this.z = z;
}
}
And I want to create a class Test without changing the class header (can't do Test<X, Y, Z>):
public class Test {
...
}
In this class should be a method, that takes a list of Triples and should return a Map with the x-value of the triple as a key and the y and z-values of the triple as the value of the map.
How can I do this without changing the class header?
You can do it. You need to make the method generic rather than the class it's in.
class Test {
static <X, Y, Z> Map<X, Pair<Y, Z>> makeMap(List<Triple<X, Y, Z>> triples) {
// your implementation
}
}
The method could be static or non-static. In either case, the generic parameters <X, Y, Z> appear immediately before the return type.
From your description, here an implementation:
public static <X, Y, Z> Map<X, Pair<Y, Z>> makeMap(List<Triple<X, Y, Z>> arg) {
return arg.stream().collect(Collectors.toMap(e -> e.x, e -> new Pair<>(e.y, e.z)));
}
I have the class GameObject:
public class GameObject{
private Coordinate coordinates;
public GameObject(){
coordinates = new Coordinate();
}
public void setCoordinates(int x, int y){
coordinates.x = x;
coordinates.y = y;
}
//More methods here
}
public class Coordinate{
public int x, y;
public Coordinate(){
}
public Coordinate(int x, int y){
this.x = x;
this.y = y;
}
public void setCoordinate(int x, int y){
this.x = x;
this.y = y;
}
And two classes Champion and Spell:
public class Spell extends GameObject{
//Some methods
}
public class Champion extends GameObject{
//Some methods
public Spell fireBall = new Spell();
}
And in my main class:
Champion character = new Champion();
If I call character.setCoordinates(200, 300); (just random numbers), the character goes to these exact coordinates. But the Spell fireBall also goes to (200, 300). So the coordinates in Spell are overriden by the setCoordinates(int x, int y) call to character. How is this possible?
TL;DR - Two classes from GameObject, Spell extends GameObject and Champion extends GameObject, override eachother coordinates. Why?
For full source code:
GameObject.java
Spell.java
Champion.java
Coordinate.java
Looking at your code in gitHub you have 2 methods:
//Set the coordinates for this GameObject
public void setCoordinates(int x, int y){
this.coordinates.x = x;
this.coordinates.y = y;
}
public void setCoordinates(Coordinate coordinates){
this.coordinates = coordinates;
}
If you ever use the 2nd one, then you are sharing the same instance of Coordinates so changing one will change the other
The solution is to copy the values instead
public void setCoordinates(Coordinate coordinates){
this.coordinates.x = coordinates.x;
this.coordinates.y = coordinates.y;
}
In the class Spell you set the coordinates:
this.startCoordinates = startCoordinates;
setCoordinates(this.startCoordinates);
Subsequently this code
if (getCoordinates().x - startCoordinates.x < range) {
is equivalent to
if (getCoordinates().x - getCoordinates().x < range) {
because getCoordinates() references the same object as startCoordinates does.
Your setter method just sets the reference, but it does not copy the object.
I'm writing most of my immutable data objects in the following style, which is somtimes described as 'next generation' or 'functional':
public class Point {
public final int x;
public final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
I would like to use the same style for data objects specified by interfaces:
public interface Point {
public final int x;
public final int y;
}
public class MyPoint {
public MyPoint(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Origin {
public Origin() {
this.x = 0;
this.y = 0;
}
}
But this is not allowed by java, which gives an error in the interface code as well as the implementations.
I can change my code to
public interface Point {
public int x();
public int y();
}
public class MyPoint {
private int mx, my;
pulic MyPoint(int x, int y) {
mx = x;
my = y;
}
public int x() {return mx;}
public int y() {return my;}
}
public class Origin {
public int x() {return 0;}
public int y() {return 0;}
}
But it is more code, and I don't think it gives nearly the same feeling of simplicity in the API.
Can you see a path out of my dilemma? Or do you personally use a third, even simpler style?
(I'm not really interested in a discussion of mutable/immutable, getterSetter/new-style or private/public fields.)
I would rather switch to use inheritance or delegation
public class Point {
public final int x;
public final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
Inheritance
public class MyPoint extends Point {
public MyPoint (int x, int y) {
super (x, y);
}
....
}
public class Origin extends Point {
public Origin () {
super (0, 0);
}
}
I have a class in Java describing a parameter (name: Param) and another class in which I declare and initialize around 100 of such parameters as:
private static final Param param_name_1 = new Param(x, y, z);
I would like to put all these objects/instances in an enum and initialize them there. What is the best method to do that?
===UPDATE===
I asked for the syntax of the enum but not like that.
I my case Param is another java class which has its own parameters, getters and setters and a constructor with the 3 parameters between the paranthesis:
public Param(intx, int y, int z){
this.x = x;
this.y = y;
this.z = z;
}
I my other class I declare and initialize 100 instances of the class Param as written above. Each x, y and z for each instance are different.
And the enum should contain the declaration of the instances and possibly also initialize them.
Assuming that you're asking about the enum syntax then you can do something like this (assuming that x, y and z are compile time constants).
public enum Param {
param_name_1(1,2,3),
param_name_2(3,4,5);
private int x;
private int y;
private int z;
private Param(int x, int y, int z) {
this.x=x;
this.y=y;
this.z=z;
}
}
An enum is a special type of class, so you can declare constructors, fields and methods as well as implement interfaces. However, they can not extend other classes.
In this case, I'd suggest final fields and getters, like this:
public enum Param {
PARAM_A(1, 2, 3),
PARAM_B(4, 5, 6),
PARAM_C(1, 3, 5);
private final int x;
private final int y;
private final int z;
private Param(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getZ() {
return z;
}
}
I think this is what you want
class Param
{
private int x, y, z;
public Param(int x, int y, int z)
{
this.x = x; this.y = y; this.z = z;
}
}
public class t
{
private enum ParamVals
{
VAL1(new Param(0,0,0)),
VAL2(new Param(1,1,1));
private Param paramVal;
private ParamVals(Param paramVal)
{
this.paramVal = paramVal;
}
public Param getVal()
{
return paramVal;
}
}
}