首页 > 解决方案 > 如何基于在最小/最大范围之外的 jSpinner 中的文本字段的无效手动编辑触发事件

问题描述

我有一个 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); 
              } }

              });

标签: javaswingjspinnerjformattedtextfield

解决方案


这是我能够使用 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
            }
        });

推荐阅读