首页 > 解决方案 > 如何使两个字段的条件?

问题描述

下午好,我需要添加几个条件来验证当前代码中的两个字段。

  1. Min 字段不得超过 Max 字段。Min <Max / 5000 <4000 禁止进入。
  2. Max 字段不得小于 Min 字段。Max <Min / 4000 <5000 禁止进入。
  3. Min 字段不应超过 Max 字段的间隔,可以少输入 500 个单位。例如:Min 4500 and Max 5000, 4400/5000, 4250/5000, 4501/5000及以上禁止进入。
  4. Min 和 Max 字段不能相等。Min = Max 禁止进入。

在此处输入图像描述 在此处输入图像描述在此处输入图像描述

代码:

import controlP5.*;

ControlP5 cp5;
Textfield O;
Textfield OO;

void setup() {
  size(700, 400);

  PFont font = createFont("arial", 18);

  cp5 = new ControlP5(this);

  O = cp5.addTextfield("MIN")
    .setPosition(20, 100)
    .setSize(200, 40);
  O.setInputFilter(ControlP5.INTEGER)
    .setFont(font)
    .setColor(color(255, 0, 0));

  OO = cp5.addTextfield("MAX")
    .setPosition(20, 170)
    .setSize(200, 40);
  OO.setInputFilter(ControlP5.INTEGER)
    .setFont(font);

  textFont(font);
}

void draw() {
  if (keyPressed && OO.isFocus()) {
    float n;
    try {
      n = Float.parseFloat(OO.getText().replace(',', '.'));
      if (!(n >= 1 && n <= 12000)) {
        throw new NumberFormatException(); // throw to catch below
      }
    } 
    catch (Exception e2) {
      String t;
      if (OO.getText().length() > 1) {
        t = OO.getText().substring(0, OO.getText().length() - 1);
      } else {
        t = "";
      }
      OO.setText(t);
    }
  }
  if (keyPressed && O.isFocus()) {
    float n;
    try {
      n = Float.parseFloat(O.getText().replace(',', '.'));
      if (!(n >= 1 && n <= 11500)) {
        throw new NumberFormatException(); // throw to catch below
      }
    } 
    catch (Exception e2) {
      String t;
      if (O.getText().length() > 1) {
        t = O.getText().substring(0, O.getText().length() - 1);
      } else {
        t = "";
      }
      O.setText(t);
    }
  }
  background(0);
  fill(255);
}

标签: javaprocessingcontrol-p5

解决方案


总的来说,这听起来像是您试图让用户输入一系列有效值(其中最小值总是小于最大值)。已经有一个 ControlP5 控制器:范围

除了允许在一个范围内设置最小值和最大值之外,还有保持最大值和最小值之间的差异至少为 500 的约束。

您可以将 Range 滑块的句柄设置为 0px 宽,基本上禁用它们,这意味着您在开始时设置的范围(通过setRangeValues)将保持不变:

import controlP5.*;

ControlP5 cp5;

Range range;

int rangeMinValue;
int rangeMaxValue;

void setup() {
  size(700, 400);

  PFont font = createFont("arial", 18);

  cp5 = new ControlP5(this);

  range = cp5.addRange("yourRange")
             // disable broadcasting since setRange and setRangeValues will trigger an event
             .setBroadcast(false) 
             .setFont(font)
             .setPosition(50,50)
             // notice the dimensions are proportional to the min/max range to avoid floating point values
             .setSize(500,40)
             // set minimum - maximum range here
             .setRange(4000,5000)
             // example: set initial (recommended) range values
             .setRangeValues(4000, 4500)
             // workaround to disable left/right handles contraining the range to 500
             .setHandleSize(0)
             // after the initialization we turn broadcast back on again
             .setBroadcast(true)
             ;
  
  textFont(font);
}

void draw() {
  background(0);
  fill(255);
}

void controlEvent(ControlEvent event) {
  if(event.isFrom("yourRange")) {
    // min and max values are stored in an array.
    // access this array with controller().arrayValue().
    // min is at index 0, max is at index 1.
    rangeMinValue = int(event.getController().getArrayValue(0));
    rangeMaxValue = int(event.getController().getArrayValue(1));
    println("range:",rangeMinValue,"->",rangeMaxValue);
  }
  
}

范围滑块:约束范围大小

一个限制是范围不能> 500。如果这是一个要求,您仍然可以手动限制值(通过设置范围 min(low)/max(high) 值):

import controlP5.*;

// range constants
final int RANGE_MIN = 4000;
final int RANGE_MAX = 5000;
// the smallest allowed difference between min/max values
final int RANGE_MIN_DIFFERENCE = 500;
final int RANGE_MID = RANGE_MIN + ((RANGE_MAX - RANGE_MIN) / 2);

ControlP5 cp5;

Range range;

int rangeMinValue;
int rangeMaxValue;

void setup() {
  size(700, 400);

  PFont font = createFont("arial", 18);

  cp5 = new ControlP5(this);

  range = cp5.addRange("yourCustomRange")
             // disable broadcasting since setRange and setRangeValues will trigger an event
             .setBroadcast(false) 
             .setFont(font)
             .setPosition(50,50)
             // notice the dimensions are proportional to the min/max range to avoid floating point values
             .setSize(500,40)
             // set minimum - maximum range here
             .setRange(RANGE_MIN, RANGE_MAX)
             // example: set initial (recommended) range values
             .setRangeValues(RANGE_MIN, RANGE_MIN + RANGE_MIN_DIFFERENCE)
             // after the initialization we turn broadcast back on again
             .setBroadcast(true)
             ;
  
  textFont(font);
}

void draw() {
  background(0);
  fill(255);
}

void controlEvent(ControlEvent event) {
  if(event.isFrom("yourCustomRange")) {
    // min and max values are stored in an array.
    // access this array with controller().arrayValue().
    // min is at index 0, max is at index 1.
    int rangeMinInt  = int(event.getController().getArrayValue(0));
    int rangeMaxInt  = int(event.getController().getArrayValue(1));
    // if the values are within the desired range, update global values
    if(rangeMaxInt - rangeMinInt >= RANGE_MIN_DIFFERENCE){
      rangeMinValue = rangeMinInt;
      rangeMaxValue = rangeMaxInt;
    }else{
      // otherwise check which side of the range should be constrained (right/max) or (left/min) to overwrite user input
      if(rangeMaxInt > RANGE_MID){
        range.setLowValue(rangeMaxInt - RANGE_MIN_DIFFERENCE);
      }else{
        range.setHighValue(rangeMinInt + RANGE_MIN_DIFFERENCE);
      }
    }
    // values to use
    println("range:",rangeMinValue,"->",rangeMaxValue);
  }
  
}

范围滑块:可编辑范围受限

如果这占用太多空间,您可以使用Numberbox,与文本字段相比,它有一些优点:

  • 您无需担心字符串到整数的转换(它默认处理数字)
  • 您可以设置最小/最大值

这是一个例子:

import controlP5.*;

ControlP5 cp5;

// range constants
final int RANGE_MIN = 4000;
final int RANGE_MAX = 5000;
// the smallest allowed difference between min/max values
final int RANGE_MIN_DIFFERENCE = 500;
final int RANGE_MID = RANGE_MIN + ((RANGE_MAX - RANGE_MIN) / 2);

int minValue;
int maxValue;

Numberbox inputMin;
Numberbox inputMax;

void setup() {
  size(700, 400);

  PFont font = createFont("arial", 18);

  cp5 = new ControlP5(this);

  inputMin = cp5.addNumberbox("minValue")
             .setPosition(100,100)
             .setSize(100,20)
             .setFont(font)
             .setScrollSensitivity(1.1)
             // set initial acceptable range
             .setMin(RANGE_MIN)
             .setMax(RANGE_MAX)
             // set default value
             .setValue(4000)
             ;
  
  inputMax = cp5.addNumberbox("maxValue")
             .setPosition(100,150)
             .setSize(100,20)
             .setFont(font)
             .setScrollSensitivity(1.1)
             // set initial acceptable range
             .setMin(RANGE_MIN)
             .setMax(RANGE_MAX)
             // set default value
             .setValue(RANGE_MID + 1)
             ;
  
  
  textFont(font);
}

void draw() {
  constrainRangeInputs();
  background(0);
  fill(255);
  text("minValue: " + minValue + "\n" +
       "maxValue: " + maxValue, 10, 15);
}

void constrainRangeInputs(){
  int rangeMinInt = (int)inputMin.getValue();
  int rangeMaxInt = (int)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);
    }
  }
}

范围数字框

逻辑约束值到最小 500 的差异并不是 100% 严格,可能还有一些我没有考虑过的其他边缘情况。它更多的是说明解决问题的方法,因此您更有能力这样做。

我建议通过Processing > Examples > Contributed Libraries > ControlP5并运行示例,特别是controllers。您可以优先考虑那些听起来更接近您当前问题的选项,但值得体验这些选项,以便您可以选择最适合您的问题的控制器/UI 元素。

该示例可能不包括控制器具有的每种方法的使用,但是底部有一个注释列表,您可以轻松地立即复制/粘贴/运行。此外,您当然还有完整的文档


推荐阅读