View Javadoc
1   package org.opentrafficsim.gui;
2   
3   import java.awt.Dimension;
4   import java.awt.GridBagConstraints;
5   import java.awt.GridBagLayout;
6   import java.beans.PropertyChangeListener;
7   
8   import javax.swing.JLabel;
9   import javax.swing.JPanel;
10  import javax.swing.SwingConstants;
11  
12  import org.djunits.locale.DefaultLocale;
13  
14  import com.bric.multislider.MultiThumbSlider;
15  import com.bric.multislider.MultiThumbSliderUI;
16  import com.bric.multislider.MultiThumbSliderUI.Thumb;
17  
18  /**
19   * Wrapper for Jeremy Wood's MultiThumbSlider.
20   * <p>
21   * Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
22   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
23   * <p>
24   * $LastChangedDate: 2015-08-30 00:16:51 +0200 (Sun, 30 Aug 2015) $, @version $Revision: 1329 $, by $Author: averbraeck $,
25   * initial version 22 dec. 2014 <br>
26   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
27   */
28  public class ProbabilityDistributionEditor extends JPanel
29  {
30      /** */
31      private static final long serialVersionUID = 20141222L;
32  
33      /** The internal MultiThumbSlider. */
34      private MultiThumbSlider<String> slider;
35  
36      /** The JLabels that indicate the current values. */
37      private JLabel[] labels;
38  
39      /**
40       * Construct a graphical ProbabilityDistributioneEditor.
41       * @param elementNames String[]; the names of the elements of the probability distribution
42       * @param values Double[]; the initial values of the probabilities (should add up to 1.0 and should have same length as
43       *            <cite>elementNames</cite>)
44       */
45      public ProbabilityDistributionEditor(final String[] elementNames, final Double[] values)
46      {
47          super(new GridBagLayout());
48          GridBagConstraints gbc = new GridBagConstraints();
49          gbc.fill = GridBagConstraints.BOTH;
50          gbc.gridx = 0;
51          gbc.gridy = 0;
52          gbc.gridwidth = 2;
53          float[] initialValues = new float[values.length - 1];
54          double sum = 0;
55          String[] reducedNames = new String[elementNames.length - 1];
56          for (int i = 0; i < values.length - 1; i++)
57          {
58              sum += values[i];
59              initialValues[i] = (float) sum;
60              reducedNames[i] = elementNames[i];
61          }
62          this.slider = new MultiThumbSlider<String>(MultiThumbSlider.HORIZONTAL, initialValues, reducedNames);
63          this.slider.setThumbOverlap(true);
64          this.slider.putClientProperty(MultiThumbSliderUI.THUMB_SHAPE_PROPERTY, Thumb.Hourglass);
65          this.slider.setThumbOverlap(true);
66          this.slider.setAutoAdding(false);
67          this.slider.setPreferredSize(new Dimension(250, 50));
68          add(this.slider, gbc);
69          gbc.gridwidth = 1;
70          this.labels = new JLabel[values.length];
71          for (int i = 0; i < values.length; i++)
72          {
73              gbc.gridy++;
74              gbc.gridx = 0;
75              JLabel caption = new JLabel(elementNames[i] + ": ");
76              caption.setHorizontalAlignment(SwingConstants.TRAILING);
77              add(caption, gbc);
78              JLabel value = new JLabel("");
79              value.setHorizontalAlignment(SwingConstants.LEADING);
80              gbc.gridx = 1;
81              add(value, gbc);
82              this.labels[i] = value;
83          }
84      }
85  
86      /**
87       * Retrieve the current probability values.
88       * @return Double[]; the probability values
89       */
90      public final Double[] getProbabilities()
91      {
92          float[] positions = this.slider.getThumbPositions();
93          Double[] result = new Double[positions.length + 1];
94          double previous = 0;
95          for (int i = 0; i < result.length - 1; i++)
96          {
97              double thisValue = positions[i];
98              result[i] = new Double(thisValue - previous);
99              previous = thisValue;
100         }
101         result[positions.length] = 1 - previous;
102         for (int i = 0; i < result.length; i++)
103         {
104             this.labels[i].setText(String.format(DefaultLocale.getLocale(), "%.3f", result[i]));
105         }
106         return result;
107     }
108 
109     /**
110      * {@inheritDoc}
111      */
112     @Override
113     public final void addPropertyChangeListener(final PropertyChangeListener pcl)
114     {
115         this.slider.addPropertyChangeListener(pcl);
116     }
117 
118     /**
119      * {@inheritDoc}
120      */
121     @Override
122     public final void removePropertyChangeListener(final PropertyChangeListener pcl)
123     {
124         this.slider.removePropertyChangeListener(pcl);
125     }
126 
127     /**
128      * {@inheritDoc}
129      */
130     @Override
131     public final void addPropertyChangeListener(final String key, final PropertyChangeListener pcl)
132     {
133         this.slider.addPropertyChangeListener(key, pcl);
134     }
135 
136     /**
137      * {@inheritDoc}
138      */
139     @Override
140     public final void removePropertyChangeListener(final String key, final PropertyChangeListener pcl)
141     {
142         this.slider.removePropertyChangeListener(key, pcl);
143     }
144 
145 }