Note that there are some explanatory texts on larger screens.

plurals
  1. POJava JSlider precision problems
    text
    copied!<p>I have a list of N JSliders (N does not change procedurally, only as I add more features. Currently N equals 4). The sum of all the sliders values must equal to 100. As one slider moves the rest of the sliders shall adjust. Each slider has values that range from 0 to 100.</p> <p>Currently I am using this logic when a slider is changed (pseudo-code):</p> <pre><code>newValue = currentSlider.getValue otherSliders = allSliders sans currentSlider othersValue = summation of otherSliders values properOthersValue = 100 - newValue ratio = properOthersValue / othersValue for slider in otherSlider slider.value = slider.getValue * ratio </code></pre> <p>The problem with this setup is slider's values are stored as ints. So as I adjust the sliders I get precision problems: sliders will twitch or not move at all depending on the ratio value. Also the total value does not always add up to 100.</p> <p>Does anyone have a solution to this problem without creating an entirely new JSlider class that supports floats or doubles?</p> <p>If you want an example of the behavior I want, visit: <a href="http://www.humblebundle.com/" rel="nofollow">Humble Indie Bundle</a> and scroll to the bottom of the page.</p> <p>thank you</p> <p>p.s. Multiplying the values by the ratio allows for the user to 'lock' values at 0. However, I am not sure what to do when 3 of the 4 sliders are at 0 and the 4th slider is at 100 and I move the 4th slider down. Using the logic above, the 3 sliders with 0 as their value stay put and the 4th slider moves to where the user puts it, which makes the total less than 100, which is improper behavior. </p> <p><strong>EDIT</strong></p> <p>Here is the SSCCE:</p> <pre><code>import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import java.awt.*; import java.util.LinkedList; public class SliderDemo { static LinkedList&lt;JSlider&gt; sliders = new LinkedList&lt;JSlider&gt;(); static class SliderListener implements ChangeListener { boolean updating = false; public void stateChanged(ChangeEvent e) { if (updating) return; updating = true; JSlider source = (JSlider)e.getSource(); int newValue = source.getValue(); LinkedList&lt;JSlider&gt; otherSliders = new LinkedList&lt;JSlider&gt;(sliders); otherSliders.remove(source); int otherValue = 0; for (JSlider slider : otherSliders) { otherValue += slider.getValue(); } int properValue = 100 - newValue; double ratio = properValue / (double)otherValue; for (JSlider slider : otherSliders) { int currentValue = slider.getValue(); int updatedValue = (int) (currentValue * ratio); slider.setValue(updatedValue); } int total = 0; for (JSlider slider : sliders) { total += slider.getValue(); } System.out.println("Total = " + total); updating = false; } } public static void main(String[] args) { JFrame frame = new JFrame("SliderDemo"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Container container = frame.getContentPane(); JPanel sliderPanel = new JPanel(new GridBagLayout()); container.add(sliderPanel); SliderListener listener = new SliderListener(); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; int sliderCount = 4; int initial = 100 / sliderCount; for (int i = 0; i &lt; sliderCount; i++) { gbc.gridy = i; JSlider slider = new JSlider(0, 100, initial); slider.addChangeListener(listener); slider.setMajorTickSpacing(50); slider.setPaintTicks(true); sliders.add(slider); sliderPanel.add(slider, gbc); } frame.pack(); frame.setVisible(true); } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload