javawindowsswingaudiojeditorpane

Java Swing HTML JEditorPane causes "Windows Background Sound" to play when pressing Enter


I would like to create a JFrame with an HTML JEditorPane. There are certain things that need to happen when the user presses ENTER.

However, as long as I keep the JEditorPane, a "Windows Background Sound" plays whenever ENTER is pressed. The sound can be heard in this YouTube video at 2:57: https://www.youtube.com/watch?v=sRTvrtuuGJQ&t=176s

I want the JEditorPane but I don't want the sound. How do I remove the sound?

Here is my code:

public static void main(String[] args) {
    // Create Frame with dimensions
    Dimension frameDimension = new Dimension(600, 400);
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setMinimumSize(frameDimension);
    frame.setSize(frameDimension);
    frame.setBackground(Color.white);


    //Create HTML Editor Pane
    JEditorPane htmlLabel = new JEditorPane("text/html", "");
    htmlLabel.setEditable(false);
    htmlLabel.setBackground(Color.WHITE);
    htmlLabel.setFont(new Font(htmlLabel.getName(), Font.PLAIN, 14));
    htmlLabel.setVisible(true);


    //IF I KEEP THIS LINE,
    //I will hear a "Windows Notification Sound"
    //whenever I press ENTER
    frame.add(htmlLabel);
    //I don't want the sound but I want this pane


    htmlLabel.addKeyListener(new KeyListener() {
        @Override
        public void keyTyped(KeyEvent e) {

        }

        @Override
        public void keyPressed(KeyEvent e) {
            //If Enter is pressed
            if(e.getKeyCode() == 10) {
                // DO STUFF
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {

        }
    });

    frame.setResizable(false);
    frame.setVisible(true);
}

By the way, my Java Version is 1.8 u221

I will appreciate any help.


Solution

  • TL;DR

    You need to remove the Action associated with pressing the ENTER key.

    htmlLabel.getInputMap().put(KeyStroke.getKeyStroke("pressed ENTER"), "none");
    

    Explanation

    JEditorPane associates pressing of combinations of keyboard keys with actions. This code shows all the registered combinations:

    for (KeyStroke ks : htmlLabel.getInputMap().allKeys()) {
        System.out.println(ks);
    }
    

    One of the lines of output, when running the above code, is:

    pressed ENTER
    

    The [default] Action associated with pressing ENTER can be obtained like so:

    htmlLabel.getActionMap().get(htmlLabel.getInputMap().get(KeyStroke.getKeyStroke("pressed ENTER")));
    

    This returns an instance of class javax.swing.text.StyledEditorKit.StyledInsertBreakAction. That class's actionPerformed method contains the following code:

    public void actionPerformed(ActionEvent e) {
        JEditorPane target = getEditor(e);
    
        if (target != null) {
            if ((!target.isEditable()) || (!target.isEnabled())) {
                UIManager.getLookAndFeel().provideErrorFeedback(target);
                return;
            }
    

    In other words, if the JEditorPane is not editable and the ENTER key is pressed, the [Windows] beep sound will be played.

    Hence, as written above, the simplest solution (in my opinion) is to simply remove the Action associated with pressing ENTER.

    Of-course, you could, alternatively, create your own Action to replace the default one.

    Note that your KeyListener still works, i.e. even after removing the Action, pressing ENTER still invokes method keyPressed.

    Refer to

    Both are from Using Swing Components lesson in Creating a GUI With Swing trail of Oracle's Java tutorials.

    Here is my rewrite of the code in your question:

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    
    import javax.swing.JEditorPane;
    import javax.swing.JFrame;
    import javax.swing.KeyStroke;
    
    public class App {
    
        public static void main(String[] args) {
            Dimension frameDimension = new Dimension(600, 400);
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setMinimumSize(frameDimension);
            frame.setSize(frameDimension);
            frame.setBackground(Color.white);
    
            // Create HTML Editor Pane
            JEditorPane htmlLabel = new JEditorPane("text/html", "");
            htmlLabel.getInputMap().put(KeyStroke.getKeyStroke("pressed ENTER"), "none");
            htmlLabel.setEditable(false);
            htmlLabel.setBackground(Color.WHITE);
            htmlLabel.setFont(new Font(htmlLabel.getName(), Font.PLAIN, 14));
            htmlLabel.setVisible(true);
    
            // IF I KEEP THIS LINE,
            // I will hear a "Windows Notification Sound"
            // whenever I press ENTER
            frame.add(htmlLabel);
            // I don't want the sound but I want this pane
    
            htmlLabel.addKeyListener(new KeyListener() {
                @Override
                public void keyTyped(KeyEvent e) {
    
                }
    
                @Override
                public void keyPressed(KeyEvent e) {
                    // If Enter is pressed
                    if (e.getKeyCode() == 10) {
                        // DO STUFF
                        System.out.println("ENTER");
                    }
                }
    
                @Override
                public void keyReleased(KeyEvent e) {
    
                }
            });
            frame.setResizable(false);
            frame.setVisible(true);
        }
    }