1

“链接” JSlider 以限制组合价值的最佳方式是什么?

想象一个格斗游戏,用户可以指定速度、敏捷性、耐力和准确性等角色特征。用户有 100 点分配,但他选择,但所有滑块的总值不能超过 100。也就是说,滑块不应该允许这样的增加。

如果用户为速度、敏捷性和耐力分别分配了 30 分,那么精度滑块应允许最多 10 分(因为 30 + 30 + 30 + 10 = 100)。尽管如此,每个滑块的范围应保持不变(在本例中为 0 到 100)。

我希望这是有道理的。谢谢您的帮助。

4

2 回答 2

5

“nichts einfacher als das” - dachte ...(插入名称:-)

基本上,所有这些增强的功能都必须在模型中实现:对于 JSlider,这是一个 BoundedRangeModel。实施/扩展并执行其价值以尊重“组合”最大值。就像是

public static 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();
            }
        }
        super.setRangeProperties(newValue, newExtent, newMin, newMax, adjusting);
    }
}

// use
LimitedBoundedRangeModel firstModel = new LimitedBoundedRangeModel(null);
LimitedBoundedRangeModel secondModel = new LimitedBoundedRangeModel(firstModel);
firstModel.limit= secondModel;

JSlider first = new JSlider(firstModel);
JSlider second = new JSlider(secondModel);

虽然简单(仅两个依赖项)和粗略(直接双向耦合),因此在野外并不真正可用,但它至少应该可以工作......但不是 - 不时打击我的那些惊喜之一; -) 视觉问题是拇指位置:

  • 单击拇指右侧时会考虑组合的最大值:拇指永远不会超过阈值
  • 拖动时,拇指可以移动到可能预期的任何地方,因为 ui 不知道模型调整 - 它只知道“本地”最大值
  • 在拖动端,拇指保持在那个无效位置..这闻起来像一个错误,因为现在拇指与模型不同步

这种不当行为的原因是 Handler 中的 changeListener: 它在拖动时不会重新计算其拇指位置(这没关系)。微妙的错误是,内部拖动标志仅在模型的调整属性被重置后才被重置,因此错过了关于最终值的最后通知......

Hack around 是调用一个额外的 changeEvent,如果调整标志从 true 变为 false

        boolean invoke =
               (adjusting != getValueIsAdjusting()) && !adjusting;
        super.setRangeProperties(newValue, newExtent, newMin, newMax, adjusting);
        if (invoke) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    fireStateChanged();   
                }
            });
        }
于 2011-09-20T08:36:37.390 回答
0

创建 4 个滑块和一些变量:最大总值(例如,100)和当前总值(0)。

当任何滑块的值修改时,请执行以下操作:

// I hope my logic isn't failing me at this point

if (slider.getValue() > (maxTotal - currentTotal))
    slider.setValue(maxTotal - currentTotal);

currentTotal = slider1.getValue() + slider2.getValue()
             + slider3.getValue() + slider4.getValue();
于 2011-09-20T08:00:50.090 回答