Author Topic: [Java] Key Events and Multiple Classes  (Read 3964 times)

0 Members and 1 Guest are viewing this topic.

Offline Munchor

  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 6199
  • Rating: +295/-121
  • Code Recycler
    • View Profile
[Java] Key Events and Multiple Classes
« on: May 24, 2011, 08:13:35 am »
I have two files:

Squared.java
Code: [Select]
import javax.swing.*;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

public class Squared {
JFrame mainFrame = new JFrame("Squared");
public int x = 5;
public int y = 5;
public boolean canRunConstructor = true;

public static void main (String[] args)
{
Squared mySquared = new Squared();
mySquared.Draw();
}
public Squared()
{
// TODO Constructors
}
public void Draw()
{
canRunConstructor = false;
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(480,320);
mainFrame.getContentPane().setLayout(null);
KeyEvents keyEvents = new KeyEvents();
mainFrame.addKeyListener(keyEvents);

BufferedImage img = null;
try {
img = ImageIO.read(new File("bin/block.png"));
} catch (IOException e) {
e.printStackTrace();
}
JLabel picLabel = new JLabel(new ImageIcon( img ));
picLabel.setBounds(x,y,40,40);

mainFrame.add(picLabel);

mainFrame.setVisible(true);
}
}

KeyEvents.java
Code: [Select]
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;


public class KeyEvents implements KeyListener {

@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 39) //Right key
{
Squared mySquared = new Squared();
mySquared.x = mySquared.x + 5;
mySquared.mainFrame.repaint();
}
System.out.println(e.getKeyCode());
}

@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub

}

@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub

}

}

What i'm trying to do is when I press <RIGHT> in the keyboard, the block moves right, any idea what's wrong? I can't detailedly explain my code now.
« Last Edit: May 25, 2011, 11:10:17 am by Scout »

Offline nemo

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1203
  • Rating: +95/-11
    • View Profile
Re: [Java] Key Events and Multiple Classes
« Reply #1 on: May 24, 2011, 10:42:55 pm »
what's wrong with your code is that everytime you press the right key, you make a new Squared object, set it's value to 10, and then you draw the frame. if you did mySquared.Draw(), you would see a new JFrame pop up everytime you press the right arrow key. i'm not certain how to fix this existing code. i would scrap it.

This is how i would do what you're trying:
you'll want to have a class which extends JPanel, implements KeyListener, and overrides the method public void paintComponent(Graphics g); paintComponent is where you'll have the code to draw the Squared. then you'll have a class called Square which holds the data for the square. the class which extends JPanel should have a JFrame and Square as instance variables. after this, whenever you press the right arrow key, update the Squared object, and call repaint();


Offline Munchor

  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 6199
  • Rating: +295/-121
  • Code Recycler
    • View Profile
Re: [Java] Key Events and Multiple Classes
« Reply #2 on: May 25, 2011, 02:49:25 am »
My problem there is the Java-talk:

Quote
you'll want to have a class which extends JPanel, implements KeyListener, and overrides the method public void paintComponent(Graphics g)

Extending, Implementing and Overriding, but I will give it a look.

Offline ZippyDee

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 729
  • Rating: +83/-8
  • Why not zoidberg?
    • View Profile
Re: [Java] Key Events and Multiple Classes
« Reply #3 on: May 25, 2011, 02:53:17 am »
Code: [Select]
public class MyClass extends JPanel implements KeyListener {
    @Override
    public void paintComponent(Graphics g){
        //your code here
    }
}
There's something about Tuesday...


Pushpins 'n' stuff...


Offline Munchor

  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 6199
  • Rating: +295/-121
  • Code Recycler
    • View Profile
Re: [Java] Key Events and Multiple Classes
« Reply #4 on: May 25, 2011, 09:30:17 am »
That implies changing the Picture Label to a graphic right? Well, I guess i'll have to try that too.

I wrote this to change my code to work with graphics:

Squared.java
Code: [Select]
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

public class Squared {
   
    public static void main(String[] args)
    {
        Squared mySquared = new Squared();
        mySquared.createAndShowGUI();
    }

    public void createAndShowGUI()
    {
        JFrame f = new JFrame("Squared");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(480,320);
        f.setResizable(false);
        f.add(new GamePanel());
        KeyEvents myKeyEvents = new KeyEvents();
        f.addKeyListener(myKeyEvents);
        f.setVisible(true);
    }
}

class GamePanel extends JPanel {
int x = 5;
int y = 5;

    public GamePanel()
    {
   
    }

    public Dimension getPreferredSize()
    {
        return new Dimension(250,200);
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(Color.black);
        g.fillRect(x,y,40,40);
    } 
}

KeyEvents.java
Code: [Select]
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPanel;

import java.awt.Graphics;

public class KeyEvents extends JPanel implements KeyListener {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 39) //Right key
{
GamePanel myGamePanel = new GamePanel();
myGamePanel.x += 5;
//So now how to update graphics?
}
}

@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub

}

@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub

}
}

My question is how to update the frame after having raised Squared.x to Squared.x+=5. Thanks.
« Last Edit: May 25, 2011, 11:11:36 am by Scout »

Offline Munchor

  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 6199
  • Rating: +295/-121
  • Code Recycler
    • View Profile
Re: [Java] Key Events and Multiple Classes
« Reply #5 on: May 26, 2011, 02:41:36 pm »
***BUMP***

Does anyone know how to do this?

Offline jnesselr

  • King Graphmastur
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2270
  • Rating: +81/-20
  • TAO == epic
    • View Profile
Re: [Java] Key Events and Multiple Classes
« Reply #6 on: May 26, 2011, 03:48:14 pm »
You've already been given the answer.  Don't create a new object each time in that keyPressed event.  Create it once, and use the same gamepanel.

Offline Munchor

  • LV13 Extreme Addict (Next: 9001)
  • *************
  • Posts: 6199
  • Rating: +295/-121
  • Code Recycler
    • View Profile
Re: [Java] Key Events and Multiple Classes
« Reply #7 on: May 26, 2011, 03:52:23 pm »
KeyEvents.java
Code: [Select]
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JPanel;

import java.awt.Graphics;

public class KeyEvents extends JPanel implements KeyListener {
GamePanel myGamePanel = new GamePanel();
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == 39) //Right key
{
myGamePanel.x += 5;
}
}

@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub

}

@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub

}
}

Squared.java
Code: [Select]
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;

public class Squared {
   
    public static void main(String[] args)
    {
        Squared mySquared = new Squared();
        mySquared.createAndShowGUI();
    }

    public void createAndShowGUI()
    {
        JFrame f = new JFrame("Squared");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setSize(480,320);
        f.setResizable(false);
        f.add(new GamePanel());
        KeyEvents myKeyEvents = new KeyEvents();
        f.addKeyListener(myKeyEvents);
        f.setVisible(true);
    }
}

class GamePanel extends JPanel {
int x = 5;
int y = 5;

    public GamePanel()
    {
   
    }

    public Dimension getPreferredSize()
    {
        return new Dimension(250,200);
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setColor(Color.black);
        g.fillRect(x,y,40,40);
    } 
}

I just did that (thanks for the tip) but the sprite still doesn't move right. How to repaint in the KeyPressed function? Thanks

Offline nemo

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1203
  • Rating: +95/-11
    • View Profile
Re: [Java] Key Events and Multiple Classes
« Reply #8 on: May 26, 2011, 05:51:57 pm »
the KeyEvents class shouldn't extend JPanel. That's why the GamePanel class exists. in the Squared class you had a new DrawingPanel, which we'll refer to as "dp1" for simplicity. dp1 is the panel added to the frame, which is seen on your screen. Then you make a new KeyEvents object, which contains a GamePanel. we'll call that dp2. then, whenever you press the right arrow key, dp2's x coordinate is incremented by 5. if the problem in your code isn't apparent by now, refer to the bolded portion of this post.

also, a pro tip. if your class contains instance variables or methods that don't refer to the class name, something's wrong. in this case, your class KeyEvents has a GamePanel object. second, your Squared class doesn't take advantage of constructors. your main method should be as simple as "new Squared();" or "new Squared().show();" -- where show is just frame.setVisible(true); lastly, it's good practice to use constants, e.g. KeyEvent.VK_RIGHT represents the right arrow key, instead of hard-coding it as 39. this makes your code more understandable (eliminating the need for the comment "Right key") and makes it easy to change which number is the right arrow key if needed. for example, you wouldn't write this:
Code: [Select]
frame.setDefaultCloseOperation(-3);

because -3 has no significant value. if you looked back on that line of code in 3 years you would have no idea what that line does, which is why JFrame.EXIT_ON_CLOSE is used.