Oktavix
Oktavix

Reputation: 151

My repaint in JFrame is not working

I have a problem with repaint in JFrame i used repaint() earlier when i was making an animation and everything worked

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

public class Draw extends JComponent implements KeyListener {

    int x = 0;
    int y = 0;

    public void paint(Graphics g){
        g.setColor(Color.BLUE);
        g.fillRect(x, y, 50, 50);
    }

    public void keyPressed(KeyEvent k) {
        if(k.getKeyCode() == KeyEvent.VK_UP){
            y -= 2;
        } else if(k.getKeyCode() == KeyEvent.VK_DOWN){
            y += 2;
        } else if(k.getKeyCode() == KeyEvent.VK_LEFT){
            x -= 2;
        } else if(k.getKeyCode() == KeyEvent.VK_RIGHT){
            x += 2;
        }

        repaint();
    }

    public void keyReleased(KeyEvent k) {}

    public void keyTyped(KeyEvent k) {}

    }

This is my draw class which if i run as an applet everything works but i don't want an applet

My frame class

import javax.swing.*;

public class Frame  {

    Draw d = new Draw();

    public Frame(){

        JFrame f = new JFrame("Game");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(800, 600);
        f.setVisible(true);

        f.add(d);
        f.addKeyListener(new Draw());
    }

}

and my Main class

public class Main {

    public static void main(String[] args) {

        Frame f = new Frame();

    }

}

The repaint() is the one not working i tested the key listener it works so why isn't the repaint() working?

Upvotes: 3

Views: 357

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

The KeyListener shouldn't be working since a JComponent by default cannot get program focus, a necessary requirement for a KeyListener to work. One solution is to make it focusable via setFocusable(true) and then call requestFocusInWindow() on it. Better to use Key Bindings (tutorial link). Note that you should be overriding paintComponent, not paint and you should not forget to call the super's method within your override.

For example

Edit: I'm wrong since a JFrame can get focus and you're adding the KeyListener to the JFrame. But your problem is that you are creating a new Draw object to do this, not to the original displayed Draw object. Your code would actually work if you use the same Draw object for both displaying the image and for KeyListener:

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

public class Draw extends JComponent implements KeyListener {
   int x = 0;
   int y = 0;

   @Override
   protected void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.setColor(Color.BLUE);
      g.fillRect(x, y, 50, 50);
   }

   public void keyPressed(KeyEvent k) {
      if (k.getKeyCode() == KeyEvent.VK_UP) {
         y -= 2;
      } else if (k.getKeyCode() == KeyEvent.VK_DOWN) {
         y += 2;
      } else if (k.getKeyCode() == KeyEvent.VK_LEFT) {
         x -= 2;
      } else if (k.getKeyCode() == KeyEvent.VK_RIGHT) {
         x += 2;
      }

      repaint();
   }

   public void keyReleased(KeyEvent k) {
   }

   public void keyTyped(KeyEvent k) {
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            Draw d = new Draw();
            JFrame f = new JFrame("Game");
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setSize(800, 600);
            f.setVisible(true);

            f.add(d);
            f.addKeyListener(d);
         }
      });
   }
}

Safer though is to use Key Bindings.

Upvotes: 3

Related Questions