问题描述
当我将鼠标指针拖到处理窗口之外时,我的程序以意外的方式做出反应。如何复制:
- 将鼠标指针悬停在“ MIN”字段上,并在按住鼠标左键的同时尝试更改该字段中数字的值。
- 在不释放左键鼠标的情况下,以平均速度或将鼠标指针向左拖动然后向右拖动,超出应用程序窗口的区域。
- 现在不满足以下条件:
- MIN
- 始终为MIN-MAX最多为500个单位。
- MAX> MIN
- MAX + MIN起有500个单位。
请注意,仅当鼠标指针移出应用程序窗口区域时才观察到这种效果。是否有消除这种影响的方法或如何避免这种影响?
如果您不将鼠标指针移到窗口大小区域上,那么一切都会正常进行!
Сode:
import controlP5.*;
ControlP5 cp5;
// range constants
final float RANGE_MIN = 7.4;
final float RANGE_MAX = 16.8;
// the smallest allowed difference between min/max values
final float RANGE_MIN_DIFFERENCE = 1;
final float RANGE_MID = RANGE_MIN + ((RANGE_MAX - RANGE_MIN) / 2);
float minValue;
float maxValue;
NumberBox inputMin;
NumberBox inputMax;
void setup() {
size(700,400);
PFont font = createFont("arial",18);
cp5 = new ControlP5(this);
inputMin = cp5.addNumberBox("minValue")
.setPosition(360,240)
.setSize(80,30)
.setColorValue(0xffffff00)
.setFont(font)
.setScrollSensitivity(1.1)
// set initial acceptable range
.setMin(RANGE_MIN)
.setMax(RANGE_MAX)
// set default value
.setMultiplier(0.01)
.setDirection(Controller.HORIZONTAL)
.setValue(7.4);
Label labelinputMin = inputMin.getCaptionLabel();
labelinputMin.setFont(font);
labelinputMin.setColor(color(#00ffff));
labelinputMin.toupperCase(false);
labelinputMin.setText("MIN");
labelinputMin.align(ControlP5.LEFT_OUTSIDE,CENTER);
labelinputMin.getStyle().setPaddingLeft(-100);
inputMax = cp5.addNumberBox("maxValue")
.setPosition(360,300)
.setSize(80,30)
.setColorValue(0xffffff00)
.setFont(font)
.setScrollSensitivity(1.1)
// set initial acceptable range
.setMin(RANGE_MIN)
.setMax(RANGE_MAX)
// set default value
.setMultiplier(0.01)
.setDirection(Controller.HORIZONTAL)
.setValue(RANGE_MID + 1);
Label labelinputMax= inputMax.getCaptionLabel();
labelinputMax.setFont(font);
labelinputMax.setColor(color(#00ffff));
labelinputMax.toupperCase(false);
labelinputMax.setText("МAX");
labelinputMax.align(ControlP5.LEFT_OUTSIDE,CENTER);
labelinputMax.getStyle().setPaddingLeft(-93);
textFont(font);
}
void draw() {
constrainRangeInputs();
background(0);
fill(255);
text("minValue: " + minValue + "\n" +
"maxValue: " + maxValue,10,15);
}
void controlEvent(ControlEvent event) {
println(event.getController().getName(),"changed value to",event.getValue(),"RANGE_MIN = ",minValue,"RANGE_MAX = ",maxValue);
}
void constrainRangeInputs() {
float rangeminint = (float)inputMin.getValue();
float rangeMaxInt = (float)inputMax.getValue();
//
if (abs(rangeMaxInt - rangeminint) < RANGE_MIN_DIFFERENCE) {
if (rangeMaxInt > RANGE_MID) {
inputMin.setValue(rangeMaxInt - RANGE_MIN_DIFFERENCE);
} else {
inputMax.setValue(rangeminint + RANGE_MIN_DIFFERENCE);
}
}
}
解决方法
此问题是由于您编写的内容混合在一起,以及处理的draw()
循环受FPS限制的原因,在您的情况下可能为60,因为您没有设置它。
constrainRangeInputs
方法由draw()
循环调用,但不是Numberbox.updateInternalEvents
方法。如果您的FPS极低,即使在draw()
方法的两个循环之间,数字框也可能会更新几次,即使我们看不到它也没有视觉上的更新。
然后,当需要draw()
循环执行该操作时,它将调用您的constrainRangeInputs()
方法。
问题在这里:
if (abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE) {
如果绝对数很高,则绝对数可以使rangeMinInt
高于rangeMaxInt
。这是何时发生的示例:
Assuming these values:
rangeMinInt = 15
rangeMaxInt = 10
RANGE_MIN_DIFFERENCE = 1
// Reading these numbers,you already know that this is supposed to be corrected by the constrainRangeInputs() method,but...
// Doing the math reveals that:
rangeMaxInt - rangeMinInt = -5
// yet:
abs(rangeMaxInt - rangeMinInt) = 5
// So:
abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE // false
// The program sees this as absolutely normal!
这与退出窗口无关(如果您将窗口的大小更改为非常宽,则可以重现该问题,我已通过实验进行了处理)。问题在于,constrainRangeInputs()
完成工作时,当前数字已经足够高,可以符合您的条件。
这是因为在RANGE_MIN_DIFFERENCE
循环的两次迭代之间,鼠标移动得足够快,足以覆盖draw()
。
您可以摆脱abs()
,轻松解决此问题。我不知道为什么它首先会很重要,但是当您从现有代码中改编它时,它可能是原始代码中的产物。
所以:更改此行
if (abs(rangeMaxInt - rangeMinInt) < RANGE_MIN_DIFFERENCE) {
为此:
if (rangeMaxInt - rangeMinInt < RANGE_MIN_DIFFERENCE) {
希望它会有所帮助,这比看起来要棘手。玩得开心!