How to use KeyListener with JFrame?

So, I tried to make the rectangle move using KeyEvent ( KeyListener ), and whenever I try to press a key, the rectangle does not move.

A rectangle is drawn, but whenever I press the left and right keys, nothing happens. I have two classes, one of which is my main class with key elements and a frame, and the other draws a rectangle and holds the function to move the rectangle.

Here is my code:

 import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; public class mainFrame extends JFrame implements KeyListener{ mainDraw Draw = new mainDraw(); public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if(key == KeyEvent.VK_D){ Draw.moveRight(); } } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) {} public mainFrame() { addKeyListener(this); setFocusable(true); setFocusTraversalKeysEnabled(false); } public static void main(String[] args) { mainFrame M1 = new mainFrame(); mainDraw Draw = new mainDraw(); JFrame frame = new JFrame("Square Move Practice"); //frame frame.setVisible(true); frame.setResizable(false); frame.setSize(600, 600); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(Draw); } } 

And now the second class:

 import java.awt.Color; import java.awt.Graphics; import javax.swing.JComponent; public class mainDraw extends JComponent{ public int x = 50; public int y = 50; public void paint(Graphics g){ g.drawRect(x, y, 50, 50); g.fillRect(x, y, 50, 50); g.setColor(Color.BLACK); } public void moveRight() { x = x + 5; y = y + 0; repaint(); } } 

Please tell me how I can move the rectangle. Thanks in advance!

+6
source share
5 answers

The rectangle does not move because you are not using the JFrame correctly. You should assign frame to new mainFrame() instead of ignoring the instance of mainFrame .

There are several other issues that @MadProgrammer points out.

Here is the code that fixes some problems:

mainFrame.java

 import java.awt.*; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.JFrame; public class mainFrame extends JFrame implements KeyListener{ private mainDraw draw; public void keyPressed(KeyEvent e) { System.out.println("keyPressed"); } public void keyReleased(KeyEvent e) { if(e.getKeyCode()== KeyEvent.VK_RIGHT) draw.moveRight(); else if(e.getKeyCode()== KeyEvent.VK_LEFT) draw.moveLeft(); else if(e.getKeyCode()== KeyEvent.VK_DOWN) draw.moveDown(); else if(e.getKeyCode()== KeyEvent.VK_UP) draw.moveUp(); } public void keyTyped(KeyEvent e) { System.out.println("keyTyped"); } public mainFrame(){ this.draw=new mainDraw(); addKeyListener(this); setFocusable(true); setFocusTraversalKeysEnabled(false); } public static void main(String[] args) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { mainFrame frame = new mainFrame(); frame.setTitle("Square Move Practice"); frame.setResizable(false); frame.setSize(600, 600); frame.setMinimumSize(new Dimension(600, 600)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(frame.draw); frame.pack(); frame.setVisible(true); } }); } } 

mainDraw.java

 import java.awt.Color; import java.awt.Graphics; import javax.swing.JComponent; public class mainDraw extends JComponent { public int x = 50; public int y = 50; public void paintComponent(Graphics g) { super.paintComponent(g); g.drawRect(x, y, 50, 50); g.fillRect(x, y, 50, 50); g.setColor(Color.BLACK); } public void moveRight() { x = x + 5; repaint(); } public void moveLeft() { x = x - 5; repaint(); } public void moveDown() { y = y + 5; repaint(); } public void moveUp() { y = y - 5; repaint(); } } 

BTW, use SwingUtilities to put the gui update code because swing objects are not thread safe.

+6
source

There are at least three questions ...

Firstly...

Your mainFrame class is extends from JFrame , but in your main method you instantiate it and ignore it, creating your own JFrame .

KeyListener registered in the mainFrame instance, i.e. it is ignored.

You have to get rid of extends JFrame as this just confuses the problem

Secondly...

KeyListener will only respond to key events, when the component to which it is registered is customizable and has direct focus, this makes it unreliable.

Instead, you should use the key binding API using the Draw panel, this will allow you to deal with focus problems.

Thirdly...

You broke the chain of colors, which means that when you move the rectangle, everything that was written earlier will remain.

You should refrain from overriding paint and use paintComponent instead. There are many reasons for this, but overall it is drawn in the background, called updating child components.

Finally, make sure you call super.paintComponent before doing anything else to provide a Graphics context for drawing

See Performing Custom Painting for more details.

+6
source

Try Thread.sleep(10) after all the reviews. This is what I did.

0
source

You should add your listener to the mainDraw class, not your mainFrame.

Good practice is not to handle keyboard and mouse events in frames and Windows.

about/

-1
source

I tried to implement listener shortcuts for the whole frame and did not succeed, finally found a way. If you want to set the listener even when focusing on another component, you must add listeners to all components.

Here is my code

Call this in your constructor:

 setShortcutListener(this); // this = JFrame when you call in in constructor 

SetShortcutListener method (JFrame):

 private void setShortcutListener(JFrame frame) { List<Component> comp_list = Common.getAllComponents(frame); for (Component component : comp_list) { component.addKeyListener(getShortcutKeyListener()); } } 

GetAllComponents method (frame); The Common class is just a class,

 public static List<Component> getAllComponents(final Container c) { Component[] comps = c.getComponents(); List<Component> compList = new ArrayList<Component>(); for (Component comp : comps) { compList.add(comp); if (comp instanceof Container) { compList.addAll(getAllComponents((Container) comp)); } } return compList; } 

GetShortcutKeyListener () method:

 public static KeyListener getShortcutKeyListener() { KeyListener listener = new KeyListener() { @Override public void keyReleased(KeyEvent evt) { if (evt.getKeyCode() == KeyEvent.VK_F3) { // What you do when F3 key pressed } else if (evt.getKeyCode() == KeyEvent.VK_F2) { // What you do when F2 key pressed } } @Override public void keyTyped(KeyEvent e) { // Do nothing } @Override public void keyPressed(KeyEvent e) { // Do nothing } }; return listener; } 

I think we have simple paths, but this code works exactly as expected. Key listeners work in any form.

Hope this answer helps someone. Thanks.

-1
source

All Articles