1 /*
2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javafx.beans.property.adapter;
27
28 import com.sun.javafx.binding.ExpressionHelper;
29 import com.sun.javafx.property.adapter.Disposer;
30 import com.sun.javafx.property.adapter.PropertyDescriptor;
31 import javafx.beans.InvalidationListener;
32 import javafx.beans.property.IntegerProperty;
33 import javafx.beans.value.ChangeListener;
34 import javafx.beans.value.ObservableValue;
35
36 import java.lang.reflect.InvocationTargetException;
37 import java.lang.reflect.UndeclaredThrowableException;
38
39 import java.security.AccessControlContext;
40 import java.security.AccessController;
41 import java.security.PrivilegedAction;
42
43 import sun.reflect.misc.MethodUtil;
44
45 /**
46 * A {@code JavaBeanIntegerProperty} provides an adapter between a regular
47 * Java Bean property of type {@code int} or {@code Integer} and a JavaFX
48 * {@code IntegerProperty}. It cannot be created directly, but a
49 * {@link JavaBeanIntegerPropertyBuilder} has to be used.
50 * <p>
51 * As a minimum, the Java Bean must implement a getter and a setter for the
52 * property. If the getter of an instance of this class is called, the property of
53 * the Java Bean is returned. If the setter is called, the value will be passed
54 * to the Java Bean property. If the Java Bean property is bound (i.e. it supports
55 * PropertyChangeListeners), this {@code JavaBeanIntegerProperty} will be
56 * aware of changes in the Java Bean. Otherwise it can be notified about
57 * changes by calling {@link #fireValueChangedEvent()}. If the Java Bean property
58 * is also constrained (i.e. it supports VetoableChangeListeners), this
59 * {@code JavaBeanIntegerProperty} will reject changes, if it is bound to an
60 * {@link javafx.beans.value.ObservableValue ObservableValue<Integer>}.
61 *
62 * @see javafx.beans.property.IntegerProperty
63 * @see JavaBeanIntegerPropertyBuilder
64 * @since JavaFX 2.1
65 */
66 public final class JavaBeanIntegerProperty extends IntegerProperty implements JavaBeanProperty<Number> {
67
68 private final PropertyDescriptor descriptor;
69 private final PropertyDescriptor.Listener<Number> listener;
70
71 private ObservableValue<? extends Number> observable = null;
72 private ExpressionHelper<Number> helper = null;
73
74 private final AccessControlContext acc = AccessController.getContext();
75
76 JavaBeanIntegerProperty(PropertyDescriptor descriptor, Object bean) {
77 this.descriptor = descriptor;
78 this.listener = descriptor.new Listener<Number>(bean, this);
79 descriptor.addListener(listener);
80 Disposer.addRecord(this, new DescriptorListenerCleaner(descriptor, listener));
81 }
82
83 /**
84 * {@inheritDoc}
85 *
86 * @throws UndeclaredThrowableException if calling the getter of the Java Bean
87 * property throws an {@code IllegalAccessException} or an
88 * {@code InvocationTargetException}.
89 */
90 @Override
91 public int get() {
92 return AccessController.doPrivileged((PrivilegedAction<Integer>) () -> {
93 try {
94 return ((Number)MethodUtil.invoke(
95 descriptor.getGetter(), getBean(), (Object[])null)).intValue();
96 } catch (IllegalAccessException e) {
97 throw new UndeclaredThrowableException(e);
98 } catch (InvocationTargetException e) {
99 throw new UndeclaredThrowableException(e);
100 }
101 }, acc);
102 }
103
104 /**
105 * {@inheritDoc}
106 *
107 * @throws UndeclaredThrowableException if calling the getter of the Java Bean
108 * property throws an {@code IllegalAccessException} or an
109 * {@code InvocationTargetException}.
110 */
111 @Override
112 public void set(final int value) {
113 if (isBound()) {
114 throw new RuntimeException("A bound value cannot be set.");
115 }
116 AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
117 try {
118 MethodUtil.invoke(descriptor.getSetter(), getBean(), new Object[] {value});
119 ExpressionHelper.fireValueChangedEvent(helper);
120 } catch (IllegalAccessException e) {
121 throw new UndeclaredThrowableException(e);
122 } catch (InvocationTargetException e) {
123 throw new UndeclaredThrowableException(e);
124 }
125 return null;
126 }, acc);
127 }
128
129 /**
130 * {@inheritDoc}
131 */
132 @Override
133 public void bind(ObservableValue<? extends Number> observable) {
134 if (observable == null) {
135 throw new NullPointerException("Cannot bind to null");
136 }
137
138 if (!observable.equals(this.observable)) {
|
1 /*
2 * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package javafx.beans.property.adapter;
27
28 import com.sun.javafx.binding.ExpressionHelper;
29 import com.sun.javafx.property.MethodHelper;
30 import com.sun.javafx.property.adapter.Disposer;
31 import com.sun.javafx.property.adapter.PropertyDescriptor;
32 import javafx.beans.InvalidationListener;
33 import javafx.beans.property.IntegerProperty;
34 import javafx.beans.value.ChangeListener;
35 import javafx.beans.value.ObservableValue;
36
37 import java.lang.reflect.InvocationTargetException;
38 import java.lang.reflect.UndeclaredThrowableException;
39
40 import java.security.AccessControlContext;
41 import java.security.AccessController;
42 import java.security.PrivilegedAction;
43
44 /**
45 * A {@code JavaBeanIntegerProperty} provides an adapter between a regular
46 * Java Bean property of type {@code int} or {@code Integer} and a JavaFX
47 * {@code IntegerProperty}. It cannot be created directly, but a
48 * {@link JavaBeanIntegerPropertyBuilder} has to be used.
49 * <p>
50 * As a minimum, the Java Bean class must implement a getter and a setter for the
51 * property. If the getter of an instance of this class is called, the property of
52 * the Java Bean is returned. If the setter is called, the value will be passed
53 * to the Java Bean property. If the Java Bean property is bound (i.e. it supports
54 * PropertyChangeListeners), this {@code JavaBeanIntegerProperty} will be
55 * aware of changes in the Java Bean. Otherwise it can be notified about
56 * changes by calling {@link #fireValueChangedEvent()}. If the Java Bean property
57 * is also constrained (i.e. it supports VetoableChangeListeners), this
58 * {@code JavaBeanIntegerProperty} will reject changes, if it is bound to an
59 * {@link javafx.beans.value.ObservableValue ObservableValue<Integer>}.
60 * </p>
61 * <p>
62 * The Java Bean class must be declared public. If that class is in a named
63 * module, then the module must {@link Module#isOpen(String,Module) open}
64 * the containing package to at least the {@code javafx.base} module
65 * (or {@link Module#isExported(String) export} the containing package
66 * unconditionally).
67 * </p>
68 *
69 * @see javafx.beans.property.IntegerProperty
70 * @see JavaBeanIntegerPropertyBuilder
71 * @since JavaFX 2.1
72 */
73 public final class JavaBeanIntegerProperty extends IntegerProperty implements JavaBeanProperty<Number> {
74
75 private final PropertyDescriptor descriptor;
76 private final PropertyDescriptor.Listener<Number> listener;
77
78 private ObservableValue<? extends Number> observable = null;
79 private ExpressionHelper<Number> helper = null;
80
81 private final AccessControlContext acc = AccessController.getContext();
82
83 JavaBeanIntegerProperty(PropertyDescriptor descriptor, Object bean) {
84 this.descriptor = descriptor;
85 this.listener = descriptor.new Listener<Number>(bean, this);
86 descriptor.addListener(listener);
87 Disposer.addRecord(this, new DescriptorListenerCleaner(descriptor, listener));
88 }
89
90 /**
91 * {@inheritDoc}
92 *
93 * @throws UndeclaredThrowableException if calling the getter of the Java Bean
94 * property throws an {@code IllegalAccessException} or an
95 * {@code InvocationTargetException}.
96 */
97 @Override
98 public int get() {
99 return AccessController.doPrivileged((PrivilegedAction<Integer>) () -> {
100 try {
101 return ((Number)MethodHelper.invoke(
102 descriptor.getGetter(), getBean(), (Object[])null)).intValue();
103 } catch (IllegalAccessException e) {
104 throw new UndeclaredThrowableException(e);
105 } catch (InvocationTargetException e) {
106 throw new UndeclaredThrowableException(e);
107 }
108 }, acc);
109 }
110
111 /**
112 * {@inheritDoc}
113 *
114 * @throws UndeclaredThrowableException if calling the getter of the Java Bean
115 * property throws an {@code IllegalAccessException} or an
116 * {@code InvocationTargetException}.
117 */
118 @Override
119 public void set(final int value) {
120 if (isBound()) {
121 throw new RuntimeException("A bound value cannot be set.");
122 }
123 AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
124 try {
125 MethodHelper.invoke(descriptor.getSetter(), getBean(), new Object[] {value});
126 ExpressionHelper.fireValueChangedEvent(helper);
127 } catch (IllegalAccessException e) {
128 throw new UndeclaredThrowableException(e);
129 } catch (InvocationTargetException e) {
130 throw new UndeclaredThrowableException(e);
131 }
132 return null;
133 }, acc);
134 }
135
136 /**
137 * {@inheritDoc}
138 */
139 @Override
140 public void bind(ObservableValue<? extends Number> observable) {
141 if (observable == null) {
142 throw new NullPointerException("Cannot bind to null");
143 }
144
145 if (!observable.equals(this.observable)) {
|