javaswingjformattedtextfield

disable beep sound in JFormattedTextField


I want to disable beep sound in JFormattedTextField, but I have some restriction.

  1. I only have access to the JFormattedTextField instance. I can't create a new subclass

  2. I can't change system setting. Other part of the program may need the beep sound


Solution

  • I want to disable beep sound in JFormattedTextField,

    Not very specific. For what Action are you trying to disable the "beep"? For example I know that in a text field you will hear the "beep" sound when you press the backspace button and you are already at the start of the text field.

    In this case the text component uses Key Bindings to perform the Action. So the backspace key invokes the "back space" action. See Key Bindings for a program to list all the key bindings.

    So if you want to disable the "beep" sound then you need to customize the Action. Below I copied (from the DefaultEditorKit) the Action used to delete a character in a text component. I made a couple of changes to disable the beep:

    static class MyDeletePrevCharAction extends TextAction {
    
        /**
         * Creates this object with the appropriate identifier.
         */
        MyDeletePrevCharAction() {
           //super(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);
                System.out.println("beep");
            }
        }
    }
    

    You can use this Action on a specific text component using:

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