0

I assigned keyboard shortcuts to buttons using my Java code with swing library. If I click on the text field before typing, it writes 2 times. I want to it writes one time.

Java code:

    button1 = new JButton("1");
    button1.addActionListener(this);
    button1.setBackground(Color.lightGray);
    //button1 normal number button
    button1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "button1");
    button1.getActionMap().put("button1", new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent e) {
            textField.setText(textField.getText() + "1");

        }
    });
    //button1 numpad number button
    button1.getInputMap(button1.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD1, 0), "button1");
    button1.getActionMap().put("button1", new AbstractAction() {

        public void actionPerformed(ActionEvent e) {
            textField.setText(textField.getText() + "1");
        }
    });

public void actionPerformed(ActionEvent actionEvent) {
    if (actionEvent.getActionCommand().equals("1")){
        textField.setText(textField.getText() + "1");
    }
}

sample screenshot

You can see in the screenshot, I pressed button 1 once when textfield is selected, but it wrote 2 times.

camickr
  • 321,443
  • 19
  • 166
  • 288
ATK
  • 103
  • 1
  • 11
  • You can refer this link. https://stackoverflow.com/questions/30925438/keystroke-hot-key-for-jbutton-in-java – Sambit Jan 02 '20 at 18:31
  • 1
    See [Calculator Panel](https://stackoverflow.com/questions/33739623/how-to-add-a-shortcut-key-for-a-jbutton-in-java/33739732#33739732) for a working example that does what you want. In the future post a proper [mre] demonstrating the problem. We can't tell if the code you posted or the "code you didn't post" is causing the problem. A proper MRE would be a JFrame with a JTextField and a JButton and a single Key Binding. Once you get the first binding working you add the second binding. – camickr Jan 02 '20 at 19:59
  • It didn't work for me. I think my gui is different then this one. – ATK Jan 03 '20 at 08:40

2 Answers2

0

Your last method looks redundant.

public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getActionCommand().equals("1")){
    textField.setText(textField.getText() + "1");
}
Cycan
  • 13
  • 3
  • I need to use this code because I added 0 to 9 numbers button in GUI. If I delete code it can't work. – ATK Jan 03 '20 at 08:39
0

Ok, so you have a text field and key bindings associated to your buttons, so when you type, both the text field and the buttons are executed and are updating the text field. Since you don't really need the text field to be editable (as you're controlling it through the buttons), make the text field non-editable.

You've also attached two action handlers to you 1 button. If you remove

button1.addActionListener(this);

You'll probably find the problem is no longer present

Working example

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());
            JTextField field = new JTextField(10);
            field.setEditable(false);
            add(field, BorderLayout.NORTH);

            JPanel pad = new JPanel(new GridLayout(0, 3));

            InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap actionMap = getActionMap();
            for (int index = 0; index < 10; index++) {
                JButton btn = new JButton();
                Action numAction = new NumberAction(field, index);

                btn.setAction(numAction);

                System.out.println(KeyStroke.getKeyStroke("pressed " + index));

                inputMap.put(KeyStroke.getKeyStroke("pressed " + index), "Pressed-" + index);
                actionMap.put("Pressed-" + index, numAction);

                pad.add(btn);
            }

            add(pad);
        }

    }

    public class NumberAction extends AbstractAction {
        private JTextField field;
        private int number;

        public NumberAction(JTextField field, int number) {
            this.field = field;
            this.number = number;

            putValue(NAME, Integer.toString(number));
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            Document doc = field.getDocument();
            try {
                doc.insertString(doc.getLength(), Integer.toString(number), null);
            } catch (BadLocationException ex) {
                ex.printStackTrace();
            }
        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • didn't work, I think I need to use this code because I have already 0-9 numbers buttons. If I delete this code, buttons don't work. – ATK Jan 03 '20 at 08:38
  • I've posted a working example, if you can't post a non-working example, this is as far as anyone can help you – MadProgrammer Jan 03 '20 at 09:17