JSpinner 不采用输入的最后一位数字

JSpinner does not take the last digit entered

提问人:guillanBesada 提问时间:11/6/2021 最后编辑:Andrew ThompsonguillanBesada 更新时间:11/6/2021 访问量:53

问:

我有一个里面的.当我通过键盘输入数值手动编辑字段时,微调器不会采用输入最后一位数字的值。例如,如果微调器中有一个 1,而我在前面输入一个 2(这将是 21),我只取 1,如果然后我在前面输入一个 3(它将是 321),我只取 21。所有这些操作都在事件中处理。这是整个类的代码。顺便说一句,如果在输入数字后,我按回车键,我会很好地得到所有数字。JSpinnerJTablekeyPressed

public class SpinnerEditor extends DefaultCellEditor
{
    JSpinner spinner;
    JSpinner.DefaultEditor editor;
    JTextField textField;
    boolean valueSet;

    // Initializes the spinner.
    public SpinnerEditor(DefaultTableModel modelo,JTable tabla) {
        super(new JTextField());
        spinner = new JSpinner();
        editor = ((JSpinner.DefaultEditor)spinner.getEditor());
        textField = editor.getTextField();
        textField.addFocusListener( new FocusListener() {
            public void focusGained( FocusEvent fe ) {
                System.err.println("Got focus");
                //textField.setSelectionStart(0);
                //textField.setSelectionEnd(1);
                SwingUtilities.invokeLater( new Runnable() {
                    public void run() {
                        if ( valueSet ) {
                            textField.setCaretPosition(1);
                        }
                    }
                });
            }
            public void focusLost( FocusEvent fe ) {
            }
        });
        textField.addActionListener( new ActionListener() {
            public void actionPerformed( ActionEvent ae ) {
                stopCellEditing();
            }
        });
        
       spinner.addChangeListener(new ChangeListener() 
        {
            public void stateChanged(ChangeEvent e) {
            
                try {
                    editor.commitEdit();
                    spinner.commitEdit();
                } catch (ParseException ex) {
                    Logger.getLogger(SpinnerEditor.class.getName()).log(Level.SEVERE, null, ex);
                }
            if(tabla.getSelectedRow()>=0)
            {
                
                String precio = tabla.getValueAt(tabla.getSelectedRow(),2).toString();
                
                int Iunidades = Integer.parseInt(spinner.getValue().toString());
                double Dprecio=Double.parseDouble(precio);
                double Total=Iunidades*Dprecio;
                
                modelo.setValueAt(String.valueOf(Iunidades),tabla.getSelectedRow(), 7);
                modelo.setValueAt(String.valueOf(Total),tabla.getSelectedRow(), 9);
                
            }                   
        }
        });
       
       ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField().addKeyListener(new KeyAdapter() { 
        //textField.addKeyListener(new KeyAdapter() {    
        public void keyPressed(KeyEvent e) 
                    {
                        char tecla=e.getKeyChar();
                        if(tecla>='0' && tecla<='9')
                        {
                            try {
                                editor.commitEdit();
                                spinner.commitEdit();
                            } catch (ParseException ex) {
                                Logger.getLogger(SpinnerEditor.class.getName()).log(Level.SEVERE, null, ex);
                            }
                            if(tabla.getSelectedRow()>=0)
                            {
                                
                                String precio = tabla.getValueAt(tabla.getSelectedRow(),2).toString();

                                int Iunidades = Integer.parseInt(spinner.getValue().toString());
                                double Dprecio=Double.parseDouble(precio);
                                double Total=Iunidades*Dprecio;

                                modelo.setValueAt(String.valueOf(Iunidades),tabla.getSelectedRow(), 7);
                                modelo.setValueAt(String.valueOf(Total),tabla.getSelectedRow(), 9);
                                System.out.println(spinner.getValue().toString());
                            }
                            
                        }
            
        }
    });
       
        
    }

    // Prepares the spinner component and returns it.
    public Component getTableCellEditorComponent(
        JTable table, Object value, boolean isSelected, int row, int column
    ) {
        if ( !valueSet ) {
            spinner.setValue(value);
        }
        SwingUtilities.invokeLater( new Runnable() {
            public void run() {
                textField.requestFocus();
            }
        });
        return spinner;
    }

    public boolean isCellEditable( EventObject eo ) {
        System.err.println("isCellEditable");
        if ( eo instanceof KeyEvent ) {
            KeyEvent ke = (KeyEvent)eo;
            System.err.println("key event: "+ke.getKeyChar());
            textField.setText(String.valueOf(ke.getKeyChar()));
            //textField.select(1,1);
            //textField.setCaretPosition(1);
            //textField.moveCaretPosition(1);
            valueSet = true;
        } else {
            valueSet = false;
        }
        return true;
    }

    // Returns the spinners current value.
    public Object getCellEditorValue() {
        return spinner.getValue();
    }

    public boolean stopCellEditing() {
        System.err.println("Stopping edit");
        try {
            editor.commitEdit();
            spinner.commitEdit();
            
        } catch ( java.text.ParseException e ) {
            JOptionPane.showMessageDialog(null,
                "Invalid value, discarding.");
        }
        return super.stopCellEditing();
    }

}
Java Swing 事件 JSpinner

评论

2赞 DontKnowMuchBut Getting Better 11/6/2021
自定义微调编辑器的目的是什么?另外,请考虑在您的问题中创建并发布一个最小的可重现示例

答:

1赞 camickr 11/6/2021 #1

.所有这些操作都在 keyPressed 事件中处理。

这是问题所在。

相反,您应该处理该事件。keyTyped

或者更好的是,您应该使用 .即使将文本粘贴到文本字段中,'DocumentListener 也会起作用。您应该始终设计 GUI,使其能够与键盘和鼠标一起使用。DocumentListener

有关详细信息和示例,请阅读 Swing 教程中关于如何编写 DocumentListener 的部分。

评论

0赞 guillanBesada 11/7/2021
我已经用keyrelease而不是keytyped修复了它,谢谢!
0赞 VGR 11/6/2021 #2

如果你只想要一个只接受 int 值并充当表格单元格编辑器的微调器,则不需要所有自定义处理:

    public class SpinnerEditor
    extends AbstractCellEditor
    implements TableCellEditor {
        private static final long serialVersionUID = 1;

        private final JSpinner spinner;

        public SpinnerEditor() {
            spinner = new JSpinner(
                new SpinnerNumberModel(1, 0, Integer.MAX_VALUE, 1));
        }

        @Override
        public Component getTableCellEditorComponent(JTable table,
                                                     Object value,
                                                     boolean selected,
                                                     int row,
                                                     int column) {
            spinner.setValue(value);
            return spinner;
        }

        @Override
        public Object getCellEditorValue() {
            return spinner.getValue();
        }
    }