我正在尝试向 java swing 应用程序添加 3 个 JSlider,以便三个滑块的总价值总和为 100。每个滑块都是一个概率,滑块 A 是将值添加到队列的概率,滑块 B是从队列中删除某个值的概率,滑块 C 是什么都不发生的概率。
示例:滑块 A 设置为 40,滑块 B 设置为 40,滑块 C 初始设置为 20。
如果用户将滑块 A 更改为 50,我希望滑块 B 和 C 的值都减少 5。这样总数仍为 100。
我知道当用户将值更改为 41 时可能会出现一些问题,因为我希望其他值保留为整数。
好的,在查看有关 BoundedRangeModel 的一些信息后,我添加了一些代码。我已经设法让滑块根据其他滑块进行更改,但我仍然不确定如何实现初始值。
此外,滑块似乎只能成对工作,而不是 3 个一组。
我将继续努力,如果我想出一个令我满意的解决方案,我会将其发布在这里。
package stackoverflow;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.BoundedRangeModel;
import javax.swing.DefaultBoundedRangeModel;
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 Controller {
public static void main(String[] args)
{
//GUI up
Frame f = new Frame();
f.setSize(600, 600);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
@SuppressWarnings("serial")
public static class Frame extends JFrame implements PropertyChangeListener, ChangeListener
{
//Sliders
private JSlider s1;
private JSlider s2;
private JSlider s3;
//Initial Values for fields (not sure how to implement)
private int inis1 = 45;
private int inis2 = 40;
private int inis3 = 15;
//Labels
private JLabel s1Label;
private JLabel s2Label;
private JLabel s3Label;
//Strings for labels
private static String s1String = "Probability of adding one to queue";
private static String s2String = "Probability of subtracting one from queue";
private static String s3String = "Probability of doing nothing";
public Frame()
{
//title of window
super("Sliders");
//Layout
//Label Panel, GridBag Setup
JPanel pane = new JPanel(new GridBagLayout());
this.add(pane);
GridBagConstraints c = new GridBagConstraints();
class LimitedBoundedRangeModel extends DefaultBoundedRangeModel {
BoundedRangeModel limit;
public LimitedBoundedRangeModel(BoundedRangeModel limit) {
this.limit = limit;
}
/**
* @inherited <p>
*/
@Override
public void setRangeProperties(int newValue, int newExtent, int newMin,
int newMax, boolean adjusting) {
if (limit != null) {
int combined = newValue + limit.getValue();
if (combined > newMax) {
newValue = newMax - limit.getValue();
}
}
boolean invoke =
(adjusting != getValueIsAdjusting()) && !adjusting;
super.setRangeProperties(newValue, newExtent, newMin, newMax, adjusting);
if (invoke) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
fireStateChanged();
}
});
}
super.setRangeProperties(newValue, newExtent, newMin, newMax, adjusting);
}
}
// use
LimitedBoundedRangeModel firstModel = new LimitedBoundedRangeModel(null);
LimitedBoundedRangeModel secondModel = new LimitedBoundedRangeModel(firstModel);
LimitedBoundedRangeModel thirdModel = new LimitedBoundedRangeModel(secondModel);
firstModel.limit = secondModel;
secondModel.limit = thirdModel;
thirdModel.limit = firstModel;
s1 = new JSlider(firstModel);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 5;
pane.add(s1, c);
s2 = new JSlider(secondModel);
c.gridx = 0;
c.gridy = 5;
c.gridwidth = 5;
pane.add(s2, c);
s3 = new JSlider(thirdModel);
c.gridx = 0;
c.gridy = 7;
c.gridwidth = 5;
pane.add(s3, c);
s1Label = new JLabel(s1String);
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 5;
pane.add(s1Label, c);
s2Label = new JLabel(s2String);
c.gridx = 0;
c.gridy = 4;
c.gridwidth = 5;
pane.add(s2Label, c);
s3Label = new JLabel(s3String);
c.gridx = 0;
c.gridy = 6;
c.gridwidth = 5;
pane.add(s3Label, c);
//enable 'tick' markers
s1.setMajorTickSpacing(25);
s1.setMinorTickSpacing(1);
s1.setPaintTicks(true);
s1.setPaintLabels(true);
s1.setSnapToTicks(true);
s2.setMajorTickSpacing(25);
s2.setMinorTickSpacing(1);
s2.setPaintTicks(true);
s2.setPaintLabels(true);
s2.setSnapToTicks(true);
s3.setMajorTickSpacing(25);
s3.setMinorTickSpacing(1);
s3.setPaintTicks(true);
s3.setPaintLabels(true);
s3.setSnapToTicks(true);
//Listening to sliders
s1.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent ce)
{
JSlider source = (JSlider)ce.getSource();
if (!source.getValueIsAdjusting())
{
int P = (int)source.getValue();
System.out.println("Probability of adding to queue is now: " + P);
/*
* TODO
* Would setting the values of the other sliders here,
* instead of using the BoundedRangeModel work?
* Tricky math would have to be used.
*/
// s2Slider.setValue();
}
}
});
s2.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent ce)
{
JSlider source = (JSlider)ce.getSource();
if (!source.getValueIsAdjusting())
{
int P = (int)source.getValue();
System.out.println("Probability of subtracting from queue is now: " + P);
}
}
});
s3.addChangeListener(new ChangeListener()
{
public void stateChanged(ChangeEvent ce)
{
JSlider source = (JSlider)ce.getSource();
if (!source.getValueIsAdjusting())
{
int P = (int)source.getValue();
System.out.println("Probability of doing nothing to the queue is now: " + P);
}
}
});
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
// TODO Auto-generated method stub
}
@Override
public void stateChanged(ChangeEvent e) {
// TODO Auto-generated method stub
}
}
}