Skip to main content
summaryrefslogtreecommitdiffstats
blob: 6c5c5e738d3901bd2b093d648e21cbd8921ffb1c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/*******************************************************************************
 * Copyright (c) 2007, 2008 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.utility.internal.model.value.swing;

import org.eclipse.jpt.utility.internal.BidiFilter;
import org.eclipse.jpt.utility.internal.BidiTransformer;
import org.eclipse.jpt.utility.internal.model.value.FilteringWritablePropertyValueModel;
import org.eclipse.jpt.utility.internal.model.value.TransformationWritablePropertyValueModel;
import org.eclipse.jpt.utility.model.value.WritablePropertyValueModel;

/**
 * This javax.swing.ButtonModel can be used to keep a listener
 * (e.g. a JRadioButton) in synch with a (typically shared)
 * PropertyValueModel that holds one value out of a set of values.
 * 
 * NOTE: Do *not* use this model with a ButtonGroup, since the
 * shared value holder and the wrappers built by this adapter will
 * keep the appropriate radio button checked. Also, this allows
 * us to uncheck all the radio buttons in a group when the shared
 * value is null.
 */
public class RadioButtonModelAdapter
	extends ToggleButtonModelAdapter
{

	// ********** constructors **********

	/**
	 * Constructor - the value holder is required.
	 */
	public RadioButtonModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object buttonValue, boolean defaultValue) {
		super(buildBooleanHolder(valueHolder, buttonValue), defaultValue);
	}

	/**
	 * Constructor - the value holder is required.
	 * The default value will be false.
	 */
	public RadioButtonModelAdapter(WritablePropertyValueModel<Object> valueHolder, Object buttonValue) {
		super(buildBooleanHolder(valueHolder, buttonValue));
	}


	// ********** static methods **********

	/**
	 * Build up a set of wrappers that will convert the
	 * specified value holder and button value to/from a boolean.
	 * 
	 * If the value holder's value matches the button value,
	 * the wrapper will return true. Likewise, if the value holder's
	 * value is set to true, the wrapper will set the value holder's
	 * value to the button value.
	 */
	public static WritablePropertyValueModel<Boolean> buildBooleanHolder(WritablePropertyValueModel<Object> valueHolder, Object buttonValue) {
		WritablePropertyValueModel<Object> filteringPVM = new FilteringWritablePropertyValueModel<Object>(valueHolder, new RadioButtonFilter(buttonValue));
		return new TransformationWritablePropertyValueModel<Object, Boolean>(filteringPVM, new RadioButtonTransformer(buttonValue));
	}


	// ********** overrides **********

	/**
	 * The user cannot de-select a radio button - the user
	 * can only *select* a radio button. Only the model can
	 * cause a radio button to be de-selected. We use the
	 * ARMED flag to indicate whether we are being de-selected
	 * by the user.
	 */
    @Override
	public void setSelected(boolean b) {
		// do not allow the user to de-select a radio button
		// radio buttons can
		if ((b == false) && this.isArmed()) {
			return;
		}
		super.setSelected(b);
	}


	// ********** inner classes **********

	/**
	 * This filter will only pass through a new value to the wrapped
	 * value holder when it matches the configured button value.
	 */
	public static class RadioButtonFilter implements BidiFilter<Object> {
		private Object buttonValue;

		public RadioButtonFilter(Object buttonValue) {
			super();
			this.buttonValue = buttonValue;
		}

		/**
		 * always return the wrapped value
		 */
		public boolean accept(Object value) {
			return true;
		}

		/**
		 * pass through the value to the wrapped property value model
		 * *only* when it matches our button value
		 */
		public boolean reverseAccept(Object value) {
			return (value != null) && value.equals(this.buttonValue);
		}

	}

	/**
	 * This transformer will convert the wrapped value to Boolean.TRUE
	 * when it matches the configured button value.
	 */
	public static class RadioButtonTransformer implements BidiTransformer<Object, Boolean> {
		private Object buttonValue;

		public RadioButtonTransformer(Object buttonValue) {
			super();
			this.buttonValue = buttonValue;
		}

		/**
		 * if the wrapped value matches our button value return true,
		 * if it is some other value return false;
		 * but if it is null simply pass it through because it will cause the
		 * button model's default value to be used
		 */
		public Boolean transform(Object value) {
			return (value == null) ? null : Boolean.valueOf(value.equals(this.buttonValue));
		}

		/**
		 * if the new value is true, pass through the our button value;
		 * otherwise pass through null
		 */
		public Object reverseTransform(Boolean value) {
			return (value.booleanValue()) ? this.buttonValue : null;
		}

	}

}

Back to the top