1 | |
package com.sun.javafx.runtime.location; |
2 | |
|
3 | |
import java.util.ArrayList; |
4 | |
import java.util.List; |
5 | |
|
6 | |
import com.sun.javafx.runtime.AssignToBoundException; |
7 | |
import com.sun.javafx.runtime.ErrorHandler; |
8 | |
import com.sun.javafx.runtime.Util; |
9 | |
|
10 | |
|
11 | |
|
12 | |
|
13 | |
|
14 | |
|
15 | 570 | public class ObjectVariable<T> |
16 | |
extends AbstractVariable<T, ObjectLocation<T>, ObjectBindingExpression<T>> |
17 | |
implements ObjectLocation<T> { |
18 | |
|
19 | |
protected T $value; |
20 | |
private List<ObjectChangeListener<T>> replaceListeners; |
21 | |
|
22 | |
public static<T> ObjectVariable<T> make() { |
23 | 2485 | return new ObjectVariable<T>(); |
24 | |
} |
25 | |
|
26 | |
public static<T> ObjectVariable<T> make(T value) { |
27 | 34 | return new ObjectVariable<T>(value); |
28 | |
} |
29 | |
|
30 | |
public static<T> ObjectVariable<T> make(boolean lazy, ObjectBindingExpression<T> binding, Location... dependencies) { |
31 | 651 | return new ObjectVariable<T>(lazy, binding, dependencies); |
32 | |
} |
33 | |
|
34 | |
public static<T> ObjectVariable<T> make(ObjectBindingExpression<T> binding, Location... dependencies) { |
35 | 4 | return new ObjectVariable<T>(false, binding, dependencies); |
36 | |
} |
37 | |
|
38 | |
|
39 | |
public static<T> ObjectVariable<T> makeBijective(ObjectLocation<T> other) { |
40 | 0 | ObjectVariable<T> me = ObjectVariable.make(); |
41 | 0 | me.bijectiveBind(other); |
42 | 0 | return me; |
43 | |
} |
44 | |
|
45 | 3755 | protected ObjectVariable() { } |
46 | |
|
47 | |
protected ObjectVariable(T value) { |
48 | 34 | this(); |
49 | 34 | $value = value; |
50 | 34 | setValid(); |
51 | 34 | } |
52 | |
|
53 | |
protected ObjectVariable(boolean lazy, ObjectBindingExpression<T> binding, Location... dependencies) { |
54 | 1162 | this(); |
55 | 1162 | bind(lazy, binding); |
56 | 1162 | addDependencies(dependencies); |
57 | 1162 | } |
58 | |
|
59 | |
protected ObjectBindingExpression<T> makeBindingExpression(final ObjectLocation<T> otherLocation) { |
60 | 570 | return new ObjectBindingExpression<T>() { |
61 | |
public T computeValue() { |
62 | 666 | return otherLocation.get(); |
63 | |
} |
64 | |
}; |
65 | |
} |
66 | |
|
67 | |
public T get() { |
68 | 9884 | if (isBound() && !isValid()) |
69 | 1251 | update(); |
70 | 9884 | return $value; |
71 | |
} |
72 | |
|
73 | |
protected T replaceValue(T newValue) { |
74 | 4724 | T oldValue = $value; |
75 | 4724 | if (!Util.isEqual(oldValue, newValue) || !isInitialized() || !isEverValid()) { |
76 | 4669 | boolean notifyDependencies = isValid() || !isInitialized() || !isEverValid(); |
77 | 4669 | $value = newValue; |
78 | 4669 | setValid(); |
79 | 4669 | notifyListeners(oldValue, newValue, notifyDependencies); |
80 | 4669 | } |
81 | |
else |
82 | 55 | setValid(); |
83 | 4724 | return newValue; |
84 | |
} |
85 | |
|
86 | |
public T set(T value) { |
87 | 2063 | if (isBound() && !Util.isEqual($value, value)) |
88 | 1 | throw new AssignToBoundException("Cannot assign to bound variable"); |
89 | 2062 | return replaceValue(value); |
90 | |
} |
91 | |
|
92 | |
public void setDefault() { |
93 | 0 | set(null); |
94 | 0 | } |
95 | |
|
96 | |
@Override |
97 | |
public void update() { |
98 | |
try { |
99 | 3343 | if (isBound() && !isValid()) |
100 | 2662 | replaceValue(binding.computeValue()); |
101 | |
} |
102 | 1 | catch (RuntimeException e) { |
103 | 1 | ErrorHandler.bindException(e); |
104 | 1 | if (isInitialized()) |
105 | 1 | replaceValue(null); |
106 | 3342 | } |
107 | 3343 | } |
108 | |
|
109 | |
public boolean isNull() { |
110 | 0 | return $value == null; |
111 | |
} |
112 | |
|
113 | |
public void addChangeListener(ObjectChangeListener<T> listener) { |
114 | 948 | if (replaceListeners == null) |
115 | 896 | replaceListeners = new ArrayList<ObjectChangeListener<T>>(); |
116 | 948 | replaceListeners.add(listener); |
117 | 948 | } |
118 | |
|
119 | |
private void notifyListeners(T oldValue, T newValue, boolean notifyDependencies) { |
120 | 4669 | if (notifyDependencies) |
121 | 3852 | invalidateDependencies(); |
122 | 4669 | if (replaceListeners != null) { |
123 | 789 | for (ObjectChangeListener<T> listener : replaceListeners) |
124 | 841 | listener.onChange(oldValue, newValue); |
125 | |
} |
126 | 4669 | } |
127 | |
} |