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 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.vaadin.ui;
  5. import java.util.Map;
  6. import com.vaadin.terminal.PaintException;
  7. import com.vaadin.terminal.PaintTarget;
  8. import com.vaadin.terminal.gwt.client.ui.VSlider;
  9. /**
  10. * A component for selecting a numerical value within a range.
  11. *
  12. * Example code: <code>
  13. * class MyPlayer extends CustomComponent implements ValueChangeListener {
  14. *
  15. * Label volumeIndicator = new Label();
  16. * Slider slider;
  17. *
  18. * public MyPlayer() {
  19. * VerticalLayout vl = new VerticalLayout();
  20. * setCompositionRoot(vl);
  21. * slider = new Slider("Volume", 0, 100);
  22. * slider.setImmediate(true);
  23. * slider.setValue(new Double(50));
  24. * vl.addComponent(slider);
  25. * vl.addComponent(volumeIndicator);
  26. * volumeIndicator.setValue("Current volume:" + 50.0);
  27. * slider.addListener(this);
  28. *
  29. * }
  30. *
  31. * public void setVolume(double d) {
  32. * volumeIndicator.setValue("Current volume: " + d);
  33. * }
  34. *
  35. * public void valueChange(ValueChangeEvent event) {
  36. * Double d = (Double) event.getProperty().getValue();
  37. * setVolume(d.doubleValue());
  38. * }
  39. * }
  40. *
  41. * </code>
  42. *
  43. * @author IT Mill Ltd.
  44. */
  45. @SuppressWarnings("serial")
  46. @ClientWidget(VSlider.class)
  47. public class Slider extends AbstractField {
  48. public static final int ORIENTATION_HORIZONTAL = 0;
  49. public static final int ORIENTATION_VERTICAL = 1;
  50. /**
  51. * Style constant representing a scrollbar styled slider. Use this with
  52. * {@link #addStyleName(String)}. Default styling usually represents a
  53. * common slider found e.g. in Adobe Photoshop. The client side
  54. * implementation dictates how different styles will look.
  55. */
  56. @Deprecated
  57. public static final String STYLE_SCROLLBAR = "scrollbar";
  58. /** Minimum value of slider */
  59. private double min = 0;
  60. /** Maximum value of slider */
  61. private double max = 100;
  62. /**
  63. * Resolution, how many digits are considered relevant after desimal point.
  64. * Must be a non-negative value
  65. */
  66. private int resolution = 0;
  67. /**
  68. * Slider orientation (horizontal/vertical), defaults .
  69. */
  70. private int orientation = ORIENTATION_HORIZONTAL;
  71. /**
  72. * Slider size in pixels. In horizontal mode, if set to -1, allow 100% width
  73. * of container. In vertical mode, if set to -1, default height is
  74. * determined by the client-side implementation.
  75. *
  76. * @deprecated
  77. */
  78. @Deprecated
  79. private int size = -1;
  80. /**
  81. * Handle (draggable control element) size in percents relative to base
  82. * size. Must be a value between 1-99. Other values are converted to nearest
  83. * bound. A negative value sets the width to auto (client-side
  84. * implementation calculates).
  85. *
  86. * @deprecated The size is dictated by the current theme.
  87. */
  88. @Deprecated
  89. private int handleSize = -1;
  90. /**
  91. * Show arrows that can be pressed to slide the handle in some increments
  92. * (client-side implementation decides the increment, usually somewhere
  93. * between 5-10% of slide range).
  94. */
  95. @Deprecated
  96. private final boolean arrows = false;
  97. /**
  98. * Default Slider constructor. Sets all values to defaults and the slide
  99. * handle at minimum value.
  100. *
  101. */
  102. public Slider() {
  103. super();
  104. super.setValue(new Double(min));
  105. }
  106. /**
  107. * Create a new slider with the caption given as parameter. All slider
  108. * values set to defaults.
  109. *
  110. * @param caption
  111. * The caption for this Slider (e.g. "Volume").
  112. */
  113. public Slider(String caption) {
  114. this();
  115. setCaption(caption);
  116. }
  117. /**
  118. * Create a new slider with given range and resolution
  119. *
  120. * @param min
  121. * @param max
  122. * @param resolution
  123. */
  124. public Slider(double min, double max, int resolution) {
  125. this();
  126. setMin(min);
  127. setMax(max);
  128. setResolution(resolution);
  129. }
  130. /**
  131. * Create a new slider with given range
  132. *
  133. * @param min
  134. * @param max
  135. */
  136. public Slider(int min, int max) {
  137. this();
  138. setMin(min);
  139. setMax(max);
  140. setResolution(0);
  141. }
  142. /**
  143. * Create a new slider with given caption and range
  144. *
  145. * @param caption
  146. * @param min
  147. * @param max
  148. */
  149. public Slider(String caption, int min, int max) {
  150. this(min, max);
  151. setCaption(caption);
  152. }
  153. /**
  154. * Gets the biggest possible value in Sliders range.
  155. *
  156. * @return the biggest value slider can have
  157. */
  158. public double getMax() {
  159. return max;
  160. }
  161. /**
  162. * Set the maximum value of the Slider. If the current value of the Slider
  163. * is out of new bounds, the value is set to new minimum.
  164. *
  165. * @param max
  166. * New maximum value of the Slider.
  167. */
  168. public void setMax(double max) {
  169. this.max = max;
  170. try {
  171. if ((new Double(getValue().toString())).doubleValue() > max) {
  172. super.setValue(new Double(max));
  173. }
  174. } catch (final ClassCastException e) {
  175. // FIXME: Handle exception
  176. /*
  177. * Where does ClassCastException come from? Can't see any casts
  178. * above
  179. */
  180. super.setValue(new Double(max));
  181. }
  182. requestRepaint();
  183. }
  184. /**
  185. * Gets the minimum value in Sliders range.
  186. *
  187. * @return the smalles value slider can have
  188. */
  189. public double getMin() {
  190. return min;
  191. }
  192. /**
  193. * Set the minimum value of the Slider. If the current value of the Slider
  194. * is out of new bounds, the value is set to new minimum.
  195. *
  196. * @param min
  197. * New minimum value of the Slider.
  198. */
  199. public void setMin(double min) {
  200. this.min = min;
  201. try {
  202. if ((new Double(getValue().toString())).doubleValue() < min) {
  203. super.setValue(new Double(min));
  204. }
  205. } catch (final ClassCastException e) {
  206. // FIXME: Handle exception
  207. /*
  208. * Where does ClassCastException come from? Can't see any casts
  209. * above
  210. */
  211. super.setValue(new Double(min));
  212. }
  213. requestRepaint();
  214. }
  215. /**
  216. * Get the current orientation of the Slider (horizontal or vertical).
  217. *
  218. * @return orientation
  219. */
  220. public int getOrientation() {
  221. return orientation;
  222. }
  223. /**
  224. * Set the orientation of the Slider.
  225. *
  226. * @param int new orientation
  227. */
  228. public void setOrientation(int orientation) {
  229. this.orientation = orientation;
  230. requestRepaint();
  231. }
  232. /**
  233. * Get the current resolution of the Slider.
  234. *
  235. * @return resolution
  236. */
  237. public int getResolution() {
  238. return resolution;
  239. }
  240. /**
  241. * Set a new resolution for the Slider.
  242. *
  243. * @param resolution
  244. */
  245. public void setResolution(int resolution) {
  246. if (resolution < 0) {
  247. return;
  248. }
  249. this.resolution = resolution;
  250. requestRepaint();
  251. }
  252. /**
  253. * Set the value of this Slider.
  254. *
  255. * @param value
  256. * New value of Slider. Must be within Sliders range (min - max),
  257. * otherwise throws an exception.
  258. * @param repaintIsNotNeeded
  259. * If true, client-side is not requested to repaint itself.
  260. * @throws ValueOutOfBoundsException
  261. */
  262. public void setValue(Double value, boolean repaintIsNotNeeded)
  263. throws ValueOutOfBoundsException {
  264. final double v = value.doubleValue();
  265. double newValue;
  266. if (resolution > 0) {
  267. // Round up to resolution
  268. newValue = (int) (v * Math.pow(10, resolution));
  269. newValue = newValue / Math.pow(10, resolution);
  270. if (min > newValue || max < newValue) {
  271. throw new ValueOutOfBoundsException(value);
  272. }
  273. } else {
  274. newValue = (int) v;
  275. if (min > newValue || max < newValue) {
  276. throw new ValueOutOfBoundsException(value);
  277. }
  278. }
  279. super.setValue(new Double(newValue), repaintIsNotNeeded);
  280. }
  281. /**
  282. * Set the value of this Slider.
  283. *
  284. * @param value
  285. * New value of Slider. Must be within Sliders range (min - max),
  286. * otherwise throws an exception.
  287. * @throws ValueOutOfBoundsException
  288. */
  289. public void setValue(Double value) throws ValueOutOfBoundsException {
  290. setValue(value, false);
  291. }
  292. /**
  293. * Set the value of this Slider.
  294. *
  295. * @param value
  296. * New value of Slider. Must be within Sliders range (min - max),
  297. * otherwise throws an exception.
  298. * @throws ValueOutOfBoundsException
  299. */
  300. public void setValue(double value) throws ValueOutOfBoundsException {
  301. setValue(new Double(value), false);
  302. }
  303. /**
  304. * Get the current Slider size.
  305. *
  306. * @return size in pixels or -1 for auto sizing.
  307. * @deprecated use standard getWidth/getHeight instead
  308. */
  309. @Deprecated
  310. public int getSize() {
  311. return size;
  312. }
  313. /**
  314. * Set the size for this Slider.
  315. *
  316. * @param size
  317. * in pixels, or -1 auto sizing.
  318. * @deprecated use standard setWidth/setHeight instead
  319. */
  320. @Deprecated
  321. public void setSize(int size) {
  322. this.size = size;
  323. switch (orientation) {
  324. case ORIENTATION_HORIZONTAL:
  325. setWidth(size, UNITS_PIXELS);
  326. break;
  327. default:
  328. setHeight(size, UNITS_PIXELS);
  329. break;
  330. }
  331. requestRepaint();
  332. }
  333. /**
  334. * Get the handle size of this Slider.
  335. *
  336. * @return handle size in percentages.
  337. * @deprecated The size is dictated by the current theme.
  338. */
  339. @Deprecated
  340. public int getHandleSize() {
  341. return handleSize;
  342. }
  343. /**
  344. * Set the handle size of this Slider.
  345. *
  346. * @param handleSize
  347. * in percentages relative to slider base size.
  348. * @deprecated The size is dictated by the current theme.
  349. */
  350. @Deprecated
  351. public void setHandleSize(int handleSize) {
  352. if (handleSize < 0) {
  353. this.handleSize = -1;
  354. } else if (handleSize > 99) {
  355. this.handleSize = 99;
  356. } else if (handleSize < 1) {
  357. this.handleSize = 1;
  358. } else {
  359. this.handleSize = handleSize;
  360. }
  361. requestRepaint();
  362. }
  363. @Override
  364. public void paintContent(PaintTarget target) throws PaintException {
  365. super.paintContent(target);
  366. target.addAttribute("min", min);
  367. if (max > min) {
  368. target.addAttribute("max", max);
  369. } else {
  370. target.addAttribute("max", min);
  371. }
  372. target.addAttribute("resolution", resolution);
  373. if (resolution > 0) {
  374. target.addVariable(this, "value",
  375. ((Double) getValue()).doubleValue());
  376. } else {
  377. target.addVariable(this, "value", ((Double) getValue()).intValue());
  378. }
  379. if (orientation == ORIENTATION_VERTICAL) {
  380. target.addAttribute("vertical", true);
  381. }
  382. if (arrows) {
  383. target.addAttribute("arrows", true);
  384. }
  385. if (size > -1) {
  386. target.addAttribute("size", size);
  387. }
  388. if (min != max && min < max) {
  389. target.addAttribute("hsize", handleSize);
  390. } else {
  391. target.addAttribute("hsize", 100);
  392. }
  393. }
  394. /**
  395. * Invoked when the value of a variable has changed. Slider listeners are
  396. * notified if the slider value has changed.
  397. *
  398. * @param source
  399. * @param variables
  400. */
  401. @Override
  402. public void changeVariables(Object source, Map variables) {
  403. super.changeVariables(source, variables);
  404. if (variables.containsKey("value")) {
  405. final Object value = variables.get("value");
  406. final Double newValue = new Double(value.toString());
  407. if (newValue != null && newValue != getValue()
  408. && !newValue.equals(getValue())) {
  409. try {
  410. setValue(newValue, true);
  411. } catch (final ValueOutOfBoundsException e) {
  412. // Convert to nearest bound
  413. double out = e.getValue().doubleValue();
  414. if (out < min) {
  415. out = min;
  416. }
  417. if (out > max) {
  418. out = max;
  419. }
  420. super.setValue(new Double(out), false);
  421. }
  422. }
  423. }
  424. }
  425. /**
  426. * ValueOutOfBoundsException
  427. *
  428. * @author IT Mill Ltd.
  429. *
  430. */
  431. public class ValueOutOfBoundsException extends Exception {
  432. private final Double value;
  433. /**
  434. * Constructs an <code>ValueOutOfBoundsException</code> with the
  435. * specified detail message.
  436. *
  437. * @param valueOutOfBounds
  438. */
  439. public ValueOutOfBoundsException(Double valueOutOfBounds) {
  440. value = valueOutOfBounds;
  441. }
  442. public Double getValue() {
  443. return value;
  444. }
  445. }
  446. @Override
  447. public Class getType() {
  448. return Double.class;
  449. }
  450. }