Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Borrowing from some of Hovercrafts solution I came up with a different approach. The basis of this approach is that the "other sliders" values are tracked at the time a slider is moved. As long as you continue to slide the same slider the frozen values are used to calculate the new values. Any rounding differences are then applied sequentially to each slider until the difference is used up. Using this approach you can have incremental changes in the slider applied evenly to all of the other sliders.</p> <p>The values in the model are the actual values of the slider and you can also use the keyboard to adjust the sliders:</p> <pre><code>import java.awt.*; import java.awt.GridLayout; import java.util.ArrayList; import java.util.List; import javax.swing.*; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; public class SliderGroup implements ChangeListener { private List&lt;JSlider&gt; sliders = new ArrayList&lt;JSlider&gt;(); private int groupSum; private boolean internalChange = false; private JSlider previousSlider; private List&lt;SliderInfo&gt; otherSliders = new ArrayList&lt;SliderInfo&gt;(); public SliderGroup(int groupSum) { this.groupSum = groupSum; } public void addSlider(JSlider slider) { sliders.add(slider); slider.addChangeListener(this); } @Override public void stateChanged(ChangeEvent e) { if (internalChange) return; internalChange = true; JSlider sourceSlider = (JSlider)e.getSource(); if (previousSlider != sourceSlider) { setupForSliding(sourceSlider); previousSlider = sourceSlider; } int newSumOfOtherSliders = groupSum - sourceSlider.getValue(); int oldSumOfOtherSliders = 0; for (SliderInfo info : otherSliders) { JSlider slider = info.getSlider(); if (slider != sourceSlider) { oldSumOfOtherSliders += info.getValue(); } } int difference = newSumOfOtherSliders - oldSumOfOtherSliders; if (oldSumOfOtherSliders == 0) { resetOtherSliders( difference / otherSliders.size() ); allocateDifference(difference % otherSliders.size(), true); internalChange = false; return; } double ratio = (double)newSumOfOtherSliders / oldSumOfOtherSliders; for (SliderInfo info : otherSliders) { JSlider slider = info.getSlider(); int oldValue = info.getValue(); int newValue = (int)Math.round(oldValue * ratio); difference += oldValue - newValue; slider.getModel().setValue( newValue ); } if (difference != 0) { allocateDifference(difference, false); } internalChange = false; } private void allocateDifference(int difference, boolean adjustZeroValue) { while (difference != 0) { for (SliderInfo info : otherSliders) { if (info.getValue() != 0 || adjustZeroValue) { JSlider slider = info.getSlider(); if (difference &gt; 0) { slider.getModel().setValue( slider.getValue() + 1 ); difference--; } if (difference &lt; 0) { slider.getModel().setValue( slider.getValue() - 1 ); difference++; } } } } } private void resetOtherSliders(int resetValue) { for (SliderInfo info : otherSliders) { JSlider slider = info.getSlider(); slider.getModel().setValue( resetValue ); } } private void setupForSliding(JSlider sourceSlider) { otherSliders.clear(); for (JSlider slider: sliders) { if (slider != sourceSlider) { otherSliders.add( new SliderInfo(slider, slider.getValue() ) ); } } } class SliderInfo { private JSlider slider; private int value; public SliderInfo(JSlider slider, int value) { this.slider = slider; this.value = value; } public JSlider getSlider() { return slider; } public int getValue() { return value; } } private static JPanel createSliderPanel(int groupSum, int sliderCount) { int sliderValue = groupSum / sliderCount; SliderGroup sg = new SliderGroup(groupSum); JPanel panel = new JPanel( new BorderLayout() ); JPanel sliderPanel = new JPanel( new GridLayout(0, 1) ); panel.add(sliderPanel, BorderLayout.CENTER); JPanel labelPanel = new JPanel( new GridLayout(0, 1) ); panel.add(labelPanel, BorderLayout.EAST); for (int i = 0; i &lt; sliderCount; i++) { JLabel label = new JLabel(); label.setText( Integer.toString(sliderValue) ); labelPanel.add( label ); JSlider slider = new JSlider(0, groupSum, sliderValue); slider.setMajorTickSpacing(25); slider.setMinorTickSpacing(5); slider.setPaintTicks(true); slider.setPaintLabels(true); slider.setPaintTrack(true); slider.addChangeListener( new LabelChangeListener(label) ); sliderPanel.add( slider ); sg.addSlider( slider ); } return panel; } static class LabelChangeListener implements ChangeListener { private JLabel label; public LabelChangeListener(JLabel label) { this.label = label; } @Override public void stateChanged(ChangeEvent e) { JSlider slider = (JSlider)e.getSource(); label.setText( Integer.toString(slider.getValue()) ); } } private static void createAndShowGui() { JPanel panel = createSliderPanel(100, 5); JFrame frame = new JFrame("SliderGroup"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(panel); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

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