如何基于最小/最大范围之外的jSpinner中文本字段的无效手动编辑来触发事件

时间:2019-07-12 16:18:18

标签: java swing jspinner jformattedtextfield

我有一个Java swing UI jSpinner组件,它接受双精度值并设置了最小和最大允许范围。问题是,当用户在组件的jFormattedTextField部分中手动输入一个超出最小/最大范围的值,并且焦点离开文本字段时,该值将立即被拒绝并还原最后一个上一个有效值(是该组件的预期行为和正确行为。

用户已请求更改行为,以便当输入无效值并且焦点离开文本字段时,而不是仅恢复为最后一个有效值,而是应将其恢复为最大或最小有效值,具体取决于是否用户输入的无效值大于或小于最大允许值。

例如,如果微调器的最小/最大范围设置为(1,10),并且用户手动输入值20,则文本字段应下注设置为10,而不是jSpinner的最大有效值模型。

我尝试了许多不同的方法来解决此问题,包括将KeyListener附加到基础JFormattedTextField以及将PropertyChangeListener附加到Jspinner的Number / Default编辑器,但是似乎主要问题是我无法获取无效值的实际值,以便我可以确定它是在最大值之上还是在最小值之下。

使用KeyListener(我意识到这不是处理JFormattedTextField输入的适当方法),我至少能够捕获按键,但是使用以下代码,我最能做的就是捕获异常,让我知道输入值超出了最小/最大范围,仅此而已。

在代码示例中,我收到的值是“ dirtyValue”,它始终是最后一个有效值,而不是实际无效的新输入用户输入。
我完全没有主意。谁能提供一些见识?

我尝试使用KeyListener,propertyChangeListener和DocumentListener。

private JFormattedTextField tf = ((JSpinner.NumberEditor)
jSpinnerTiming.getEditor()).getTextField();

((JSpinner.DefaultEditor)jSpinnerTiming.getEditor()).getTextField().
              addKeyListener(new KeyListener(){

              @Override public void keyPressed(KeyEvent e) { 

              }

              @Override public void keyReleased(KeyEvent e) { 

              }

              @Override public void keyTyped(KeyEvent e) { 
    try {        tf.commitEdit(); } catch
              (ParseException e1) { // TODO Auto-generated catch block
              e1.printStackTrace(); } 
    double dirtyValue = (double)tf.getValue(); 
    double max = ALLOWABLE_MAX;
    double min = ALLOWABLE_MIN;
              if (dirtyValue > max) { 
    jSpinnerTiming.setValue(max);
              ; } else if(dirtyValue < min){
              jSpinnerTiming.setValue(min); 
              } }

              });

3 个答案:

答案 0 :(得分:0)

问题在于JSpinner将所有内容保留在内部。编辑器安装了一个AbstractFormatter,它永远不允许低于最小值或高于最大值,因此您永远没有机会对这些条件做出反应。

由于几乎不可能拦截现有AbstractFormatter的行为,因此我将创建没有最小或最大限制的JSpinner,并在ChangeListener中手动实施这些限制:

Unit

答案 1 :(得分:0)

这是我可以使用FocusListener进行工作的解决方案,尽管我不确定它的正确性。

private JFormattedTextField tf = ((JSpinner.DefaultEditor) jSpinnerTiming.getEditor()).getTextField();
((JSpinner.DefaultEditor)jSpinnerTiming.getEditor()).getTextField().addFocusListener(new  FocusListener() {

            @Override
            public void focusLost(FocusEvent e) {
                // The unchecked user input value 
                double dirtyValue = Double.parseDouble(tf.getText());

                // Get Minimum and Maximum values from jSpinner's Model 
                double max = (Double) ((SpinnerNumberModel) jSpinnerTiming.getModel()).getMaximum();//MAX_ALLOWED_RATE
                double min = (Double) ((SpinnerNumberModel) jSpinnerTiming.getModel()).getMinimum();//LOWEST_ALLOWABLE_RATE;

                if (dirtyValue > max) { 
                    jSpinnerTiming.setValue(max);
                } else if(dirtyValue < min){
                    jSpinnerTiming.setValue(min);
                } 
            }
            @Override
            public void focusGained(FocusEvent e) {
                // TODO Auto-generated method stub
            }
        });

答案 2 :(得分:0)

您还可以(通过自定义AbstractFormatter来更改JFormattedTextField的{​​{1}}的{​​{1}}的{​​{1}}的{​​{1}},例如以下代码:

DefaultEditor