You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Slider.java 9.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. * Copyright 2000-2014 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.ui;
  17. import com.vaadin.shared.ui.slider.SliderOrientation;
  18. import com.vaadin.shared.ui.slider.SliderServerRpc;
  19. import com.vaadin.shared.ui.slider.SliderState;
  20. /**
  21. * A component for selecting a numerical value within a range.
  22. *
  23. * @author Vaadin Ltd.
  24. */
  25. public class Slider extends AbstractField<Double> {
  26. private SliderServerRpc rpc = new SliderServerRpc() {
  27. @Override
  28. public void valueChanged(double value) {
  29. /*
  30. * Client side updates the state before sending the event so we need
  31. * to make sure the cached state is updated to match the client. If
  32. * we do not do this, a reverting setValue() call in a listener will
  33. * not cause the new state to be sent to the client.
  34. *
  35. * See #12133.
  36. */
  37. getUI().getConnectorTracker().getDiffState(Slider.this)
  38. .put("value", value);
  39. try {
  40. setValue(value, true);
  41. } catch (final ValueOutOfBoundsException e) {
  42. // Convert to nearest bound
  43. double out = e.getValue().doubleValue();
  44. if (out < getState().minValue) {
  45. out = getState().minValue;
  46. }
  47. if (out > getState().maxValue) {
  48. out = getState().maxValue;
  49. }
  50. Slider.super.setValue(new Double(out), false);
  51. }
  52. }
  53. };
  54. /**
  55. * Default slider constructor. Sets all values to defaults and the slide
  56. * handle at minimum value.
  57. *
  58. */
  59. public Slider() {
  60. super();
  61. registerRpc(rpc);
  62. super.setValue(new Double(getState().minValue));
  63. }
  64. /**
  65. * Create a new slider with the caption given as parameter.
  66. *
  67. * The range of the slider is set to 0-100 and only integer values are
  68. * allowed.
  69. *
  70. * @param caption
  71. * The caption for this slider (e.g. "Volume").
  72. */
  73. public Slider(String caption) {
  74. this();
  75. setCaption(caption);
  76. }
  77. /**
  78. * Create a new slider with the given range and resolution.
  79. *
  80. * @param min
  81. * The minimum value of the slider
  82. * @param max
  83. * The maximum value of the slider
  84. * @param resolution
  85. * The number of digits after the decimal point.
  86. */
  87. public Slider(double min, double max, int resolution) {
  88. this();
  89. setMin(min);
  90. setMax(max);
  91. setResolution(resolution);
  92. }
  93. /**
  94. * Create a new slider with the given range that only allows integer values.
  95. *
  96. * @param min
  97. * The minimum value of the slider
  98. * @param max
  99. * The maximum value of the slider
  100. */
  101. public Slider(int min, int max) {
  102. this();
  103. setMin(min);
  104. setMax(max);
  105. setResolution(0);
  106. }
  107. /**
  108. * Create a new slider with the given caption and range that only allows
  109. * integer values.
  110. *
  111. * @param caption
  112. * The caption for the slider
  113. * @param min
  114. * The minimum value of the slider
  115. * @param max
  116. * The maximum value of the slider
  117. */
  118. public Slider(String caption, int min, int max) {
  119. this(min, max);
  120. setCaption(caption);
  121. }
  122. @Override
  123. public SliderState getState() {
  124. return (SliderState) super.getState();
  125. }
  126. @Override
  127. public SliderState getState(boolean markAsDirty) {
  128. return (SliderState) super.getState(markAsDirty);
  129. }
  130. /**
  131. * Gets the maximum slider value
  132. *
  133. * @return the largest value the slider can have
  134. */
  135. public double getMax() {
  136. return getState(false).maxValue;
  137. }
  138. /**
  139. * Set the maximum slider value. If the current value of the slider is
  140. * larger than this, the value is set to the new maximum.
  141. *
  142. * @param max
  143. * The new maximum slider value
  144. */
  145. public void setMax(double max) {
  146. getState().maxValue = max;
  147. if (getValue() > max) {
  148. setValue(max);
  149. }
  150. }
  151. /**
  152. * Gets the minimum slider value
  153. *
  154. * @return the smallest value the slider can have
  155. */
  156. public double getMin() {
  157. return getState(false).minValue;
  158. }
  159. /**
  160. * Set the minimum slider value. If the current value of the slider is
  161. * smaller than this, the value is set to the new minimum.
  162. *
  163. * @param max
  164. * The new minimum slider value
  165. */
  166. public void setMin(double min) {
  167. getState().minValue = min;
  168. if (getValue() < min) {
  169. setValue(min);
  170. }
  171. }
  172. /**
  173. * Get the current orientation of the slider (horizontal or vertical).
  174. *
  175. * @return {@link SliderOrientation#HORIZONTAL} or
  176. * {@link SliderOrientation#VERTICAL}
  177. */
  178. public SliderOrientation getOrientation() {
  179. return getState(false).orientation;
  180. }
  181. /**
  182. * Set the orientation of the slider.
  183. *
  184. * @param orientation
  185. * The new orientation, either
  186. * {@link SliderOrientation#HORIZONTAL} or
  187. * {@link SliderOrientation#VERTICAL}
  188. */
  189. public void setOrientation(SliderOrientation orientation) {
  190. getState().orientation = orientation;
  191. }
  192. /**
  193. * Get the current resolution of the slider. The resolution is the number of
  194. * digits after the decimal point.
  195. *
  196. * @return resolution
  197. */
  198. public int getResolution() {
  199. return getState(false).resolution;
  200. }
  201. /**
  202. * Set a new resolution for the slider. The resolution is the number of
  203. * digits after the decimal point.
  204. *
  205. * @throws IllegalArgumentException
  206. * if resolution is negative.
  207. *
  208. * @param resolution
  209. */
  210. public void setResolution(int resolution) {
  211. if (resolution < 0) {
  212. throw new IllegalArgumentException(
  213. "Cannot set a negative resolution to Slider");
  214. }
  215. getState().resolution = resolution;
  216. }
  217. /**
  218. * Sets the value of the slider.
  219. *
  220. * @param value
  221. * The new value of the slider.
  222. * @param repaintIsNotNeeded
  223. * If true, client-side is not requested to repaint itself.
  224. * @throws ValueOutOfBoundsException
  225. * If the given value is not inside the range of the slider.
  226. * @see #setMin(double) {@link #setMax(double)}
  227. */
  228. @Override
  229. protected void setValue(Double value, boolean repaintIsNotNeeded) {
  230. final double v = value.doubleValue();
  231. final int resolution = getResolution();
  232. double newValue;
  233. if (resolution > 0) {
  234. // Round up to resolution
  235. newValue = (int) (v * Math.pow(10, resolution));
  236. newValue = newValue / Math.pow(10, resolution);
  237. if (getMin() > newValue || getMax() < newValue) {
  238. throw new ValueOutOfBoundsException(value);
  239. }
  240. } else {
  241. newValue = (int) v;
  242. if (getMin() > newValue || getMax() < newValue) {
  243. throw new ValueOutOfBoundsException(value);
  244. }
  245. }
  246. getState().value = newValue;
  247. super.setValue(newValue, repaintIsNotNeeded);
  248. }
  249. @Override
  250. public void setValue(Double newFieldValue) {
  251. super.setValue(newFieldValue);
  252. getState().value = newFieldValue;
  253. }
  254. /*
  255. * Overridden to keep the shared state in sync with the AbstractField
  256. * internal value. Should be removed once AbstractField is refactored to use
  257. * shared state.
  258. *
  259. * See tickets #10921 and #11064.
  260. */
  261. @Override
  262. protected void setInternalValue(Double newValue) {
  263. super.setInternalValue(newValue);
  264. if (newValue == null) {
  265. newValue = 0.0;
  266. }
  267. getState().value = newValue;
  268. }
  269. /**
  270. * Thrown when the value of the slider is about to be set to a value that is
  271. * outside the valid range of the slider.
  272. *
  273. * @author Vaadin Ltd.
  274. *
  275. */
  276. public class ValueOutOfBoundsException extends RuntimeException {
  277. private final Double value;
  278. /**
  279. * Constructs an <code>ValueOutOfBoundsException</code> with the
  280. * specified detail message.
  281. *
  282. * @param valueOutOfBounds
  283. */
  284. public ValueOutOfBoundsException(Double valueOutOfBounds) {
  285. value = valueOutOfBounds;
  286. }
  287. /**
  288. * Gets the value that is outside the valid range of the slider.
  289. *
  290. * @return the value that is out of bounds
  291. */
  292. public Double getValue() {
  293. return value;
  294. }
  295. }
  296. @Override
  297. public Class<Double> getType() {
  298. return Double.class;
  299. }
  300. }