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.BooleanProperty;
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 JavaBeanBooleanProperty} provides an adapter between a regular
47 * Java Bean property of type {@code boolean} or {@code Boolean} and a JavaFX
48 * {@code BooleanProperty}. It cannot be created directly, but a
49 * {@link JavaBeanBooleanPropertyBuilder} 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 JavaBeanBooleanProperty} 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 JavaBeanBooleanProperty} will reject changes, if it is bound to an
60 * {@link javafx.beans.value.ObservableValue ObservableValue<Boolean>}.
61 *
62 * @see javafx.beans.property.BooleanProperty
63 * @see JavaBeanBooleanPropertyBuilder
64 * @since JavaFX 2.1
65 */
66 public final class JavaBeanBooleanProperty extends BooleanProperty implements JavaBeanProperty<Boolean> {
67
68 private final PropertyDescriptor descriptor;
69 private final PropertyDescriptor.Listener<Boolean> listener;
70
71 private ObservableValue<? extends Boolean> observable = null;
72 private ExpressionHelper<Boolean> helper = null;
73
74 private final AccessControlContext acc = AccessController.getContext();
75
76 JavaBeanBooleanProperty(PropertyDescriptor descriptor, Object bean) {
77 this.descriptor = descriptor;
78 this.listener = descriptor.new Listener<Boolean>(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 boolean get() {
92 return AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
93 try {
94 return (Boolean)MethodUtil.invoke(descriptor.getGetter(), getBean(), (Object[])null);
95 } catch (IllegalAccessException e) {
96 throw new UndeclaredThrowableException(e);
97 } catch (InvocationTargetException e) {
98 throw new UndeclaredThrowableException(e);
99 }
100 }, acc);
101 }
102
103 /**
104 * {@inheritDoc}
105 *
106 * @throws UndeclaredThrowableException if calling the getter of the Java Bean
107 * property throws an {@code IllegalAccessException} or an
108 * {@code InvocationTargetException}.
109 */
110 @Override
111 public void set(final boolean value) {
112 if (isBound()) {
113 throw new RuntimeException("A bound value cannot be set.");
114 }
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 Boolean> 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.BooleanProperty;
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 JavaBeanBooleanProperty} provides an adapter between a regular
46 * Java Bean property of type {@code boolean} or {@code Boolean} and a JavaFX
47 * {@code BooleanProperty}. It cannot be created directly, but a
48 * {@link JavaBeanBooleanPropertyBuilder} 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 JavaBeanBooleanProperty} 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 JavaBeanBooleanProperty} will reject changes, if it is bound to an
59 * {@link javafx.beans.value.ObservableValue ObservableValue<Boolean>}.
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.BooleanProperty
70 * @see JavaBeanBooleanPropertyBuilder
71 * @since JavaFX 2.1
72 */
73 public final class JavaBeanBooleanProperty extends BooleanProperty implements JavaBeanProperty<Boolean> {
74
75 private final PropertyDescriptor descriptor;
76 private final PropertyDescriptor.Listener<Boolean> listener;
77
78 private ObservableValue<? extends Boolean> observable = null;
79 private ExpressionHelper<Boolean> helper = null;
80
81 private final AccessControlContext acc = AccessController.getContext();
82
83 JavaBeanBooleanProperty(PropertyDescriptor descriptor, Object bean) {
84 this.descriptor = descriptor;
85 this.listener = descriptor.new Listener<Boolean>(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 boolean get() {
99 return AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> {
100 try {
101 return (Boolean)MethodHelper.invoke(descriptor.getGetter(), getBean(), (Object[])null);
102 } catch (IllegalAccessException e) {
103 throw new UndeclaredThrowableException(e);
104 } catch (InvocationTargetException e) {
105 throw new UndeclaredThrowableException(e);
106 }
107 }, acc);
108 }
109
110 /**
111 * {@inheritDoc}
112 *
113 * @throws UndeclaredThrowableException if calling the getter of the Java Bean
114 * property throws an {@code IllegalAccessException} or an
115 * {@code InvocationTargetException}.
116 */
117 @Override
118 public void set(final boolean value) {
119 if (isBound()) {
120 throw new RuntimeException("A bound value cannot be set.");
121 }
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 Boolean> observable) {
141 if (observable == null) {
142 throw new NullPointerException("Cannot bind to null");
143 }
144
145 if (!observable.equals(this.observable)) {
|