亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何根據最小/最大范圍外的 jSpinner 中文本字段的無效手動編輯觸發事件

如何根據最小/最大范圍外的 jSpinner 中文本字段的無效手動編輯觸發事件

Helenr 2023-03-23 14:15:47
我有一個 java swing UI jSpinner 組件,它接受雙精度值并設置了最小和最大允許范圍。問題是,當用戶在組件的 jFormattedTextField 部分中手動輸入一個值,該值超出最小/最大范圍并且焦點離開文本字段時,該值會立即被拒絕并恢復為上一個有效值,(是組件的預期和正確行為)。用戶已請求更改行為,以便當輸入無效值并且焦點離開文本字段而不是僅僅恢復到最后一個有效值時,它應該恢復到最大或最小有效值,具體取決于用戶是否輸入大于最大允許值或小于允許最小值的無效值。例如,如果微調器的最小/最大范圍設置為 (1,10) 并且用戶手動輸入值 20,則文本字段應設置為 10,而不是 jSpinner 模型中存在的最后一個有效值。我已經嘗試了很多不同的方法來解決這個問題,包括將 KeyListener 附加到底層的 JFormattedTextField 以及將 PropertyChangeListener 附加到 Jspinner 的數字/默認編輯器,但似乎主要問題是我無法獲得無效的值的實際值,以便我可以確定它是否超出范圍,高于最大值或低于最小值。使用 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 回答

?
慕斯709654

TA貢獻1840條經驗 獲得超5個贊

這是我能夠使用 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

            }

        });


查看完整回答
反對 回復 2023-03-23
?
慕無忌1623718

TA貢獻1744條經驗 獲得超4個贊

問題是 JSpinner 將所有內容都保留在內部。編輯器安裝了一個AbstractFormatter,它永遠不允許低于最小值或高于最大值,因此您永遠沒有機會對這些條件做出反應。


由于攔截現有 AbstractFormatter 的行為幾乎是不可能的,因此我只創建沒有最小值或最大值的 JSpinner,并在 ChangeListener 中手動強制執行這些邊界:


private static JSpinner createSpinner() {


    double initialValue = 20;


    SpinnerModel model =

        new SpinnerNumberModel(initialValue, null, null, 1d);


    model.addChangeListener(e -> {

        double value = ((Number) model.getValue()).doubleValue();

        if (value < ALLOWABLE_MIN) {

            EventQueue.invokeLater(() -> model.setValue(ALLOWABLE_MIN));

        } else if (value > ALLOWABLE_MAX) {

            EventQueue.invokeLater(() -> model.setValue(ALLOWABLE_MAX));

        }

    });


    return new JSpinner(model);

}


查看完整回答
反對 回復 2023-03-23
?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

您還可以更改的(AbstractFormatter通過自定義),如以下代碼:JFormattedTextFieldDefaultEditorJSpinnerAbstractFormatterFactory


import java.awt.Dimension;

import java.text.ParseException;

import java.util.Objects;

import javax.swing.JButton;

import javax.swing.JFormattedTextField;

import javax.swing.JFormattedTextField.AbstractFormatter;

import javax.swing.JFormattedTextField.AbstractFormatterFactory;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.JSpinner;

import javax.swing.JSpinner.DefaultEditor;

import javax.swing.SpinnerNumberModel;


public class Main {


    public static class IntegerFormatter extends AbstractFormatter {

        private final int min, max;


        public IntegerFormatter(final int min, final int max) {

            this.min = min;

            this.max = max;

        }


        @Override

        public Object stringToValue(final String text) throws ParseException {

            try {

                //This is where we compare for out of bounds values:

                final int val = Integer.parseInt(text);

                if (val < min)

                    return min;

                if (val > max)

                    return max;

                return val;

            }

            catch (final NumberFormatException nfx) {

                //Find where in the string is the parsing error (so as to return ParseException accordingly).

                int i = 0;

                for (final int cp: text.codePoints().toArray()) {

                    if (!Character.isDigit(cp))

                        throw new ParseException("Not a digit.", i);

                    ++i;

                }

                //Should not happen:

                throw new ParseException("Failed to parse input \"" + text + "\".", 0);

            }

        }


        @Override

        public String valueToString(final Object value) throws ParseException {

            return Objects.toString(value);

        }

    }


    public static class IntegerFormatterFactory extends AbstractFormatterFactory {

        private final int min, max;


        public IntegerFormatterFactory(final int min, final int max) {

            this.min = min;

            this.max = max;

        }


        @Override

        public AbstractFormatter getFormatter(final JFormattedTextField tf) {

            if (!(tf.getFormatter() instanceof IntegerFormatter))

                return new IntegerFormatter(min, max);

            return tf.getFormatter();

        }

    }


    public static void main(final String[] args) {

        final SpinnerNumberModel model = new SpinnerNumberModel(0, -10, 10, 1);

        final JSpinner spin = new JSpinner(model);

        spin.setPreferredSize(new Dimension(100, 25));


        ((DefaultEditor) spin.getEditor()).getTextField().setFormatterFactory(

                new IntegerFormatterFactory((Integer) model.getMinimum(), (Integer) model.getMaximum())

        );


        final JPanel contents = new JPanel(); //FlowLayout.

        contents.add(spin);

        contents.add(new JButton("Click me to change focus!"));


        final JFrame frame = new JFrame("Spinner out of bounds");

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().add(contents);

        frame.pack();

        frame.setLocationRelativeTo(null);

        frame.setVisible(true);

    }

}



查看完整回答
反對 回復 2023-03-23
  • 3 回答
  • 0 關注
  • 201 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號