0

I'm writing a code using Java Swing to press the right button when I type a number key. But I can't find what I want through search. This is my code and I can't understand why this isn't working. Please help me..

import javax.swing.*;
import java.awt.Dimension;
import java.awt.event.*;

class class01 {

    public static void main(String[] args) {

        JFrame f = new JFrame("Key event test"); 
        f.setSize(230, 500);
        f.setLayout(null);
        f.setVisible(true);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JLabel label = new JLabel(); 

        JButton button1 = new JButton("Coffe"); 
        button1.setSize(100, 100);
        button1.setLocation(0, 0);

        JButton button2 = new JButton("Latte");
        button2.setSize(100, 100);
        button2.setLocation(0, 100);

        JButton button3 = new JButton("Espresso");
        button3.setSize(100, 100);
        button3.setLocation(100, 100);

        JButton button4 = new JButton("Vanilla Latte");
        button4.setSize(100, 100);
        button4.setLocation(100, 0);

        f.add(button1); 
        f.add(button2);
        f.add(button3);
        f.add(button4);

        // Show message when the corresponding button is pressed.
        button1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                button1.keyPressed(KeyEvent.VK_1);
                JOptionPane.showMessageDialog(f.getComponent(0), "Coffee selected");
            }
        });
        button2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                button2.keyPressed(KeyEvent.VK_2);
                JOptionPane.showMessageDialog(f.getComponent(0), "Latte selected");
            }
        });
        button3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                button3.keyPressed(KeyEvent.VK_3);
                JOptionPane.showMessageDialog(f.getComponent(0), "Espresso selected");
            }
        });
        button4.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                button4.keyPressed(KeyEvent.VK_4);
                JOptionPane.showMessageDialog(f.getComponent(0), "Vanilla Latte selected");
            }
        });
    }
}
khelwood
  • 55,782
  • 14
  • 81
  • 108
Patrick195
  • 7
  • 1
  • 3
  • Be sure to use Swing Threading correctly. See https://stackoverflow.com/questions/18976990/best-practice-to-start-a-swing-application on how to start up your application properly. – Wim Deblauwe Nov 06 '18 at 20:10

3 Answers3

0

The code you are showing does exactly one thing: attach action listeners to your buttons..

Meaning: when you click the button, then the listener will be called.

You need a generic keyboard listener that translates key events into calls to the appropriate button, respectively action listener instead.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
0

From what I understand, essentially you want to have the same operation of a button assigned to a specific key stroke.

Things you want to avoid are KeyListener, especially because you have other focusable components in the view, namely buttons, which will steal keyboard focus and render the KeyListener useless. This is why, in almost all cases, you want to avoid KeyListener.

A better and more reliable solution would be to use the Key Bindings API, which overcomes this focus related issue, but it also encourages the use of reusable components of work through the Actions API

Something like...

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.StringJoiner;
import javax.swing.AbstractAction;
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;

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() {
            JTextField field = new JTextField(10);
            field.setEditable(false);
            field.setFocusable(false);

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "Pressed.One");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_2, 0), "Pressed.Two");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_3, 0), "Pressed.Three");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_4, 0), "Pressed.Four");

            am.put("Pressed.One", new OrderAction(1, field));
            am.put("Pressed.Two", new OrderAction(2, field));
            am.put("Pressed.Three", new OrderAction(3, field));
            am.put("Pressed.Four", new OrderAction(4, field));

            JButton btnOne = new JButton(new OrderAction(1, field));
            JButton btnTwo = new JButton(new OrderAction(2, field));
            JButton btnThree = new JButton(new OrderAction(3, field));
            JButton btnFour = new JButton(new OrderAction(4, field));

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();

            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.gridx = 0;
            gbc.gridy = 1;
            add(btnOne, gbc);
            gbc.gridx++;
            add(btnTwo, gbc);
            gbc.gridx = 0;
            gbc.gridy++;
            add(btnThree, gbc);
            gbc.gridx++;
            add(btnFour, gbc);

            gbc.gridx = 0;
            gbc.gridy = 0;

            gbc.gridwidth = 2;
            add(field, gbc);
        }

        protected class OrderAction extends AbstractAction {

            private int value;
            private JTextField field;

            public OrderAction(int value, JTextField field) {
                this.value = value;
                this.field = field;
                switch (value) {
                    case 1:
                        putValue(NAME, "Coffe");
                        break;
                    case 2:
                        putValue(NAME, "Latte");
                        break;
                    case 3:
                        putValue(NAME, "Espresso");
                        break;
                    case 4:
                        putValue(NAME, "Vanilla Latte");
                        break;
                }
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                StringJoiner sj = new StringJoiner("; ");
                if (field.getText() != null && field.getText().length() > 0) {
                    sj.add(field.getText());
                }
                sj.add(Integer.toString(value));
                field.setText(sj.toString());
            }

        }

    }

}

Note, you could apply the key bindings directly to each button instead

Now, if you want to "visually" press the button on a key stroke, I would recommend either creating a custom JButton or factory method, which could allow for a more simplified implementation, but the basic idea would be to define a key binding and Action which simply called the buttons doClick method, for example

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.StringJoiner;
import javax.swing.AbstractAction;
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;

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() {
            JTextField field = new JTextField(10);
            field.setEditable(false);
            field.setFocusable(false);

            JButton btnOne = new JButton(new OrderAction(1, field));
            JButton btnTwo = new JButton(new OrderAction(2, field));
            JButton btnThree = new JButton(new OrderAction(3, field));
            JButton btnFour = new JButton(new OrderAction(4, field));

            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_1, 0), "Pressed.One");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_2, 0), "Pressed.Two");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_3, 0), "Pressed.Three");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_4, 0), "Pressed.Four");

            am.put("Pressed.One", new ProxyAction(btnOne));
            am.put("Pressed.Two", new ProxyAction(btnTwo));
            am.put("Pressed.Three", new ProxyAction(btnThree));
            am.put("Pressed.Four", new ProxyAction(btnFour));

            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();

            gbc.weightx = 1;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;
            gbc.gridx = 0;
            gbc.gridy = 1;
            add(btnOne, gbc);
            gbc.gridx++;
            add(btnTwo, gbc);
            gbc.gridx = 0;
            gbc.gridy++;
            add(btnThree, gbc);
            gbc.gridx++;
            add(btnFour, gbc);

            gbc.gridx = 0;
            gbc.gridy = 0;

            gbc.gridwidth = 2;
            add(field, gbc);
        }

        protected class ProxyAction extends AbstractAction {

            private JButton btn;

            public ProxyAction(JButton btn) {
                this.btn = btn;
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                btn.doClick();
            }

        }

        protected class OrderAction extends AbstractAction {

            private int value;
            private JTextField field;

            public OrderAction(int value, JTextField field) {
                this.value = value;
                this.field = field;
                switch (value) {
                    case 1:
                        putValue(NAME, "Coffe");
                        break;
                    case 2:
                        putValue(NAME, "Latte");
                        break;
                    case 3:
                        putValue(NAME, "Espresso");
                        break;
                    case 4:
                        putValue(NAME, "Vanilla Latte");
                        break;
                }
            }

            @Override
            public void actionPerformed(ActionEvent e) {
                StringJoiner sj = new StringJoiner("; ");
                if (field.getText() != null && field.getText().length() > 0) {
                    sj.add(field.getText());
                }
                sj.add(Integer.toString(value));
                field.setText(sj.toString());
            }

        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
-1

When you do this:

button1.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            button1.keyPressed(KeyEvent.VK_1);
            JOptionPane.showMessageDialog(f.getComponent(0), "Coffee selected");
        }
    });

You are telling button1 what to do when somebody clicks on the button. The line with keyPressed should not be there (it does not compile even).

What you need to do is listen for key presses by adding a KeyListener to the frame like this:

f.addKeyListener(new KeyAdapter() {
        @Override
        public void keyTyped(KeyEvent e) {
            if( e.getKeyChar() == KeyEvent.VK_1) {
                JOptionPane.showMessageDialog(f.getComponent(0), "Coffee selected");
            }
        }
    });

I repeated the showMessageDialog, but you should extract the actual logic into a method and call that method from within the KeyListener on the frame and the ActionListener on the button.

Wim Deblauwe
  • 25,113
  • 20
  • 133
  • 211