0

I'm a beginner at java and I'm trying to make a square that moves in response to arrow keys. I've tried a lot of things but it just won't work. There are probably obvious errors in my code/ in my understanding of the code so if anyone could point them out that would be really helpful. Main class: import java.awt.; import javax.swing.;

public class mainClass2 {

public static void main(String[] args) {
    JFrame window = new JFrame();
    window.setSize(600,400);
    window.setVisible(true);
    window.getContentPane().setBackground(Color.WHITE);
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    boolean constant = true;
    graphics2 DC = new graphics2();
    window.add(DC);}

    }

Graphics class:

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

public class graphics2 extends JComponent implements KeyListener{
    public static int x1;
    public static int y1;
    public static int xvelocity = 0;
    public static int yvelocity = 0;


    public void paintComponent(Graphics g){
        graphics2 thing = new graphics2();
        this.addKeyListener(thing);
        System.out.println(x1);
        System.out.println(y1);
        Graphics2D g2 =(Graphics2D)g;
        Rectangle rect = new Rectangle(x1,y1,200,200);
        g2.setColor(Color.red);
        rect.setLocation(x1,y1);
        g2.fill(rect);
        repaint();
        }
    @Override
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_RIGHT) {
           x1+=10;
        // TODO Auto-generated method stub
        if(e.getKeyCode()== KeyEvent.VK_LEFT) {
            x1-=10;
        }
   }    
    }
    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub      
    }
   @Override
   public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }
B P
  • 11
  • 1

2 Answers2

2

Let's start with...

public void paintComponent(Graphics g){
    graphics2 thing = new graphics2();
    this.addKeyListener(thing);
    System.out.println(x1);
    System.out.println(y1);
    Graphics2D g2 =(Graphics2D)g;
    Rectangle rect = new Rectangle(x1,y1,200,200);
    g2.setColor(Color.red);
    rect.setLocation(x1,y1);
    g2.fill(rect);
    repaint();
}

You're creating a new instance of graphics2 and adding a KeyListener to that instance, but since that instance is never added to anything which could possibly display it, it will never be eligible for receiving key events.

Painting should paint the current state and work as quickly as possible. Creating short lived objects in paintComponent (including the creation of your rect) is generally a bad idea, as it could put unnecessary strain on your system and degrade performance.

Also, calling repaint(); inside paintComponent is a very, very bad idea. paintComponent called be called for any number of reasons, doing this is going to setup a cycle of updates which will consume the CPU and bring your system to its knees (yes, I've done it before).

To schedule regular updates, a better choice would be to use a Swing Timer, see How to use Swing Timers

Another issue is, you component isn't focusable, so it will never be able to receive keyboard focus and won't receive key events.

KeyListener is a poor choice, which has well documented limitations (just search "KeyListener doesn't work"). Instead, you should be using the Key Bindings API which will solve the limitations of the KeyListener

You may also want to have a look at How to use Key Bindings instead of Key Listeners and Key bindings vs. key listeners in Java

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
0

Add your graphics2 as a key listener and a component to your JFrame (Which I assume you are using) instead:

graphics2 graphics = new graphics2();

JFrame frame = new JFrame("Your Frame");
frame.add(graphics);
frame.addKeyListener(graphics);

Remove this line of code from graphics2 above:

this.addKeyListener(this);
camo5hark
  • 214
  • 1
  • 5