Контекст
Я пишу фрагмент кода, имеющий 1+ ползунков.Эти ползунки образуют группу.Сумма значений ползунков этой группы всегда должна составлять 100. Однако, как НУЖНАЯ функция, пользователь может отключить и включить (добавить / удалить) ползунки из этой группы.Поэтому для этого необходимо, чтобы значения ползунков были правильно отрегулированы.
После попытки кодирования моей собственной группы я решил поискать лучший / протестированный и реализованный код.Он улучшился по сравнению с моим, однако появились некоторые проблемы.
Основная проблема
При добавлении или удалении ползунков путем выбора или отмены выбора флажок вызывает ошибки, и ползунки останавливаютсяза работой.Обратите внимание, что добавление в этом сценарии означает просто включение ранее отключенного ползунка (сняв флажок).
![Example of the current issue](https://i.stack.imgur.com/X80r6.png)
ПредварительныйРешение
Приведенный ниже код был найден в stackoverflow.Я реализовал в своем коде, но так как не могу опубликовать его, я решил настроить код, найденный в примере stackoverflow, для представления моего сценария.
Как?
Любая помощь очень ценится.Я не уверен, как подойти к решению этой проблемы, не вызывая больше ошибок.Я попытался заново настроить исчисление, выполненное в методе обновления, но это просто вызвало больше глупостей.Я не нахожу продуктивным размещение всех моих попыток здесь, потому что stackoverflow сказал бы, что это слишком много кода, и потому что я не уверен, что это поможет найти ответ.
Ссылки
https://stackoverflow.com/a/21391448/2280645
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ConnectedSliders {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
JSlider s0 = new JSlider(0, 100, 30);
JSlider s1 = new JSlider(0, 100, 40);
JSlider s2 = new JSlider(0, 100, 30);
SliderGroup sliderGroup = new SliderGroup();
//sliderGroup.add(s0);
//sliderGroup.add(s1);
//sliderGroup.add(s2);
JPanel panel = new JPanel(new GridLayout(0, 3));
panel.add(s0);
panel.add(createListeningLabel(s0));
panel.add(createCheckBox(s0, sliderGroup));
panel.add(s1);
panel.add(createListeningLabel(s1));
panel.add(createCheckBox(s1, sliderGroup));
panel.add(s2);
panel.add(createListeningLabel(s2));
panel.add(createCheckBox(s2, sliderGroup));
panel.add(createListeningLabel(s0, s1, s2));
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(panel);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static JLabel createListeningLabel(final JSlider... sliders) {
final JLabel label = new JLabel("");
for (JSlider slider : sliders) {
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
int sum = 0;
for (JSlider slider : sliders) {
sum += slider.getValue();
}
label.setText("Sum: " + sum);
}
});
}
return label;
}
private static JLabel createListeningLabel(final JSlider slider) {
final JLabel label = new JLabel("");
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
label.setText(String.valueOf(slider.getValue()));
}
});
return label;
}
private static JCheckBox createCheckBox(final JSlider slider, SliderGroup group) {
final JCheckBox checkBox = new JCheckBox();
checkBox.setSelected(true);
checkBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED) {
group.add(slider);
slider.setEnabled(true);
} else if(e.getStateChange() == ItemEvent.DESELECTED) {
group.remove(slider);
slider.setEnabled(false);
}
}
});
return checkBox;
}
}
class SliderGroup {
private final Map<JSlider, Integer> values;
private final LinkedList<JSlider> candidates;
private final ChangeListener changeListener;
private boolean updating = false;
SliderGroup() {
this.values = new HashMap<JSlider, Integer>();
this.candidates = new LinkedList<JSlider>();
changeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
update(source);
}
};
}
private void update(JSlider source) {
if (updating) {
return;
}
updating = true;
int delta = source.getValue() - values.get(source);
if (delta > 0) {
distributeRemove(delta, source);
} else {
distributeAdd(delta, source);
}
for (JSlider slider : candidates) {
values.put(slider, slider.getValue());
}
updating = false;
}
private void distributeRemove(int delta, JSlider source) {
int counter = 0;
int remaining = delta;
while (remaining > 0) {
JSlider slider = candidates.removeFirst();
counter++;
if (slider == source) {
candidates.addLast(slider);
} else {
if (slider.getValue() > 0) {
slider.setValue(slider.getValue() - 1);
remaining--;
counter = 0;
}
candidates.addLast(slider);
if (remaining == 0) {
break;
}
}
if (counter > candidates.size()) {
String message = "Can not distribute " + delta + " among " + candidates;
//System.out.println(message);
//return;
throw new IllegalArgumentException(message);
}
}
}
private void distributeAdd(int delta, JSlider source) {
int counter = 0;
int remaining = -delta;
while (remaining > 0) {
JSlider slider = candidates.removeLast();
counter++;
if (slider == source) {
candidates.addFirst(slider);
} else {
if (slider.getValue() < slider.getMaximum()) {
slider.setValue(slider.getValue() + 1);
remaining--;
counter = 0;
}
candidates.addFirst(slider);
if (remaining == 0) {
break;
}
}
if (counter > candidates.size()) {
String message = "Can not distribute " + delta + " among " + candidates;
//System.out.println(message);
//return;
throw new IllegalArgumentException(message);
}
}
}
void add(JSlider slider) {
candidates.add(slider);
values.put(slider, slider.getValue());
slider.addChangeListener(changeListener);
}
void remove(JSlider slider) {
candidates.remove(slider);
values.remove(slider);
slider.removeChangeListener(changeListener);
}
}