N 個の JSliders のリストがあります (N は手続き的には変更されません。機能を追加するときだけです。現在、N は 4 です)。すべてのスライダー値の合計は 100 に等しくなければなりません。1 つのスライダーが移動すると、残りのスライダーが調整されます。各スライダーには、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
このセットアップの問題は、スライダーの値が int として格納されることです。そのため、スライダーを調整すると、精度の問題が発生します。比率の値に応じて、スライダーがけいれんしたり、まったく動かなかったりします。また、合計値が常に 100 になるとは限りません。
float または double をサポートするまったく新しい 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);
}
}