我有一个 N JSlider 的列表(N 在程序上不会改变,只有当我添加更多功能时。目前 N 等于 4)。所有滑块值的总和必须等于 100。当一个滑块移动时,其余滑块应进行调整。每个滑块的值范围从 0 到 100。
目前我在更改滑块时使用此逻辑(伪代码):
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
此设置的问题是滑块的值存储为整数。因此,当我调整滑块时,我会遇到精度问题:滑块会根据比率值抽动或根本不移动。此外,总值并不总是等于 100。
有没有人在不创建支持浮点数或双精度数的全新 JSlider 类的情况下解决这个问题?
如果您想要我想要的行为示例,请访问:Humble Indie Bundle并滚动到页面底部。
谢谢你
ps 将值乘以比率允许用户将值“锁定”为 0。但是,当 4 个滑块中的 3 个为 0 且第 4 个滑块为 100 并且我移动第 4 个滑块时,我不确定该怎么做向下。使用上面的逻辑,以 0 为值的 3 个滑块保持不变,第 4 个滑块移动到用户放置的位置,这使得总数小于 100,这是不正确的行为。
编辑
这是SSCCE:
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<JSlider> sliders = new LinkedList<JSlider>();
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<JSlider> otherSliders = new LinkedList<JSlider>(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 < 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);
}
}