Search code examples
javaswingjtextfieldjpasswordfield

Empty jtextfield/jpassword delete sound


Well, am working on a java project which requires input from the user. I realised that if the user press the backspace when there are no characters in the field, a window warning sound is heard. How can I stop this please. My system is windows 10 if at all the behavior may be different on different platforms. Thank you.


Solution

  • behavior may be different on different platforms.

    Yes, the behaviour can be different because it is controlled by the LAF, so you should not really be changing it.

    But to understand how Swing works you need to understand that Swing uses an Action provided by the DefaultEditorKit to provide the editing functions of text components.

    Following is the code for the current "delete previous character" Action (taken from the DefaultEditKit):

    /*
     * Deletes the character of content that precedes the
     * current caret position.
     * @see DefaultEditorKit#deletePrevCharAction
     * @see DefaultEditorKit#getActions
     */
    static class DeletePrevCharAction extends TextAction {
    
        /**
         * Creates this object with the appropriate identifier.
         */
        DeletePrevCharAction() {
            super(DefaultEditorKit.deletePrevCharAction);
        }
    
        /**
         * The operation to perform when this action is triggered.
         *
         * @param e the action event
         */
        public void actionPerformed(ActionEvent e) {
            JTextComponent target = getTextComponent(e);
            boolean beep = true;
            if ((target != null) && (target.isEditable())) {
                try {
                    Document doc = target.getDocument();
                    Caret caret = target.getCaret();
                    int dot = caret.getDot();
                    int mark = caret.getMark();
                    if (dot != mark) {
                        doc.remove(Math.min(dot, mark), Math.abs(dot - mark));
                        beep = false;
                    } else if (dot > 0) {
                        int delChars = 1;
    
                        if (dot > 1) {
                            String dotChars = doc.getText(dot - 2, 2);
                            char c0 = dotChars.charAt(0);
                            char c1 = dotChars.charAt(1);
    
                            if (c0 >= '\uD800' && c0 <= '\uDBFF' &&
                                c1 >= '\uDC00' && c1 <= '\uDFFF') {
                                delChars = 2;
                            }
                        }
    
                        doc.remove(dot - delChars, delChars);
                        beep = false;
                    }
                } catch (BadLocationException bl) {
                }
            }
            if (beep) {
                UIManager.getLookAndFeel().provideErrorFeedback(target);
            }
        }
    }
    

    If you don't like the beep then you would need to create your own custom Action to remove the beep sound. (ie. don't provide the error feedback). Once you customize the Action you can than change a single text field using:

    textField.getActionMap().put(DefaultEditorKit.deletePrevCharAction, new MyDeletePrevCharAction());
    

    Or you can change all text fields using:

    ActionMap am = (ActionMap)UIManager.get("TextField.actionMap");
    am.put(DefaultEditorKit.deletePrevCharAction, new MyDeletePrevCharAction());