链接的JSliders具有最大组合值

Pet*_*ter 1 java swing jslider

什么是"联系"JSliders以限制合并价值的最佳方式?

想象一下格斗游戏,用户可以指定角色特征,如速度,敏捷性,耐力和准确性.然而,用户被给予100分来分配,但是所有滑块的总值不得超过100.也就是说,滑块不应允许这样的增加.

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

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

kle*_*tra 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);
Run Code Online (Sandbox Code Playgroud)

虽然简单(仅两个家属)和原始(直接双向耦合)并且因此在野外并不真正可用,但它至少应该起作用......但不是 - 这些惊喜之一不时打击我; - )视觉问题是拇指位置:

  • 当点击拇指右侧时,组合的最大值得到尊重:拇指从不移动到门槛上
  • 拖动时,拇指可以移动到任何可能出现的位置,因为ui不知道模型调整 - 它只知道"本地"最大值
  • 在拖尾端,拇指保持在那个无效的位置..它闻起来像一个臭虫,因为现在拇指与模型的外出同步

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

如果调整标志从true变为false,则Hack是调用另一个changeEvent的触发器

        boolean invoke =
               (adjusting != getValueIsAdjusting()) && !adjusting;
        super.setRangeProperties(newValue, newExtent, newMin, newMax, adjusting);
        if (invoke) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    fireStateChanged();   
                }
            });
        }
Run Code Online (Sandbox Code Playgroud)