2

I'm doing a calculator in java, to make easyly, and don't put a document filter to the jtextfield. I opted for making the jtextfield not editable and adding a key listener, but when you press de delete button it makes an error sound.

I've go to change system's sounds in configuration, I have changed the system's sounds, and I discover that the sound it's made by "predetermined bip", and makes the sound "Windows Background". I can change my option and don't listen the sound, but I want this game to do it downloadable in the internet.

Here is a simple example: If you press the delete key in the Text Field it' going to make sound:

public Example() {
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBounds(0, 0,250,200);
        setLayout(null);
        javax.swing.JTextField jTextField1 = new javax.swing.JTextField();
        jTextField1.setEditable(false);
        jTextField1.setBounds(30,50,180,60);
        add(jTextField1);
    }
    public static void main(String args[]) {
        Example a = new Example();
        a.setVisible(true);
    }
}

In that code the textfield was not editable, in the next code the Text Field it is not going to make sound:

    public Example() {
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setBounds(0, 0,250,200);
        setLayout(null);
        javax.swing.JTextField jTextField1 = new javax.swing.JTextField();
        jTextField1.setEditable(true);
        jTextField1.setBounds(30,50,180,60);
        add(jTextField1);
    }
    public static void main(String args[]) {
        Example a = new Example();
        a.setVisible(true);
    }
}

It's because the text field is editable.

I'will appreciate if you can help me, telling me how to fix it or how to change systems sound in code, or whatever you think can help me.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • Simple solution: use a DocumentFilter. Never use a KeyListener on a Swing text component as this will cause problems with baseline functioning of the component -- as you're finding out. – Hovercraft Full Of Eels Jul 06 '19 at 10:52
  • Also never set bounds of a text component as that also incapacitates its basic functioning. Set its column and font properties instead. – Hovercraft Full Of Eels Jul 06 '19 at 10:53
  • In your simple example I get a sound whether the text field is editable or not. I would guess this is because the text field has focus. In a calculator app, the text field would not have focus so this should not be an issue. Instead focus would be on the buttons of the calculator. Check out: https://stackoverflow.com/a/33739732/131872 for an example that uses Key Bindings so the user can click on a button or type a number to update the calculator display. Note, in the linked example you would set the text field to be non focusable, so focus is placed on a button. – camickr Jul 06 '19 at 14:29

1 Answers1

0

The sound that you're getting from pressing the del key will occur even if the JTextField is editable, and is an OS-dependent response to the key being pressed. The way around this is to prevent the del key from registering that it has been pressed, and the way to do this is to use key bindings to make the del key cause no response in the GUI -- give a do-nothing action in response to the del key's being pressed when the text field has focus. For example:

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class Example extends JFrame {
    public Example() {
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        // setBounds(0, 0,250,200);
        // setLayout(null);

        JPanel panel = new JPanel();
        int gap = 40;
        panel.setBorder(BorderFactory.createEmptyBorder(gap, gap, gap, gap));

        JTextField jTextField1 = new JTextField(20);
        jTextField1.setEditable(false);
        panel.add(jTextField1);

        // get input and action maps to do key binding
        InputMap inputMap = jTextField1.getInputMap(JComponent.WHEN_FOCUSED);
        ActionMap actionMap = jTextField1.getActionMap();

        // the key stroke that we want to change bindings on: delete key
        KeyStroke delKeyStroke = KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0);

        // tell the input map to map the key stroke to a String of our choosing
        inputMap.put(delKeyStroke, delKeyStroke.toString());

        // map this same key String to an action that does **nothing**
        actionMap.put(delKeyStroke.toString(), new AbstractAction() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // do nothing
            }
        });

        add(panel);
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(() -> {
            Example example = new Example();
            example.pack();
            example.setLocationRelativeTo(null);
            example.setVisible(true);
        });
    }
}

Side recommendations:

  • Avoid using KeyListeners with text components as this can lead to undesired and non-standard behavior. Use DocumentListeners and DocumentFilters instead.
  • Avoid setting bounds of text components since this will also lead to undesired and non-standard behaviors, especially with JTextAreas that don't show scroll bars when they are placed within JScrollPanes. Instead set the properties of the text component such as the column and Font properties.
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373