I will show you two different codes to demonstrate what i'm asking for. The First code work fine it includes the JFrame and KeyListener in one class however what i want is to separate them.
First Code Below...
public class Fgui extends JFrame implements KeyListener{
private JPanel jp;
private Icon background = new ImageIcon(getClass().getResource("back2.png"));
private Icon monster = new ImageIcon(getClass().getResource("mol.png"));
protected JLabel mon;
private JLabel backG;
protected int monX = 300;
private int monY = 225;
protected int monDX = 0;
private int monDY = 0;
protected JLabel ct = new JLabel("Change Text");
protected int code;
public Fgui(){
super("Crazy Monster Eating Game");
this.setSize(750,400);
this.setLayout(null);
mon = new JLabel(monster);
backG = new JLabel(background);
this.addKeyListener(this);
this.add(mon);
mon.setSize(150,150);
mon.setLocation(monX, 225);
this.add(ct);
ct.setSize(750,20);
ct.setLocation(0,0);
this.add(backG);
backG.setSize(750,400);
backG.setLocation(0,0);
}
public void keyPressed(KeyEvent e) {
code = e.getKeyCode();
if(code == KeyEvent.VK_LEFT){
monDX = -40;
ct.setText("left key pressed");
monX = monDX+monX;
}
else if(code == KeyEvent.VK_RIGHT){
monDX = 40;
ct.setText("right key pressed");
monX = monDX+monX;
}else if(code == KeyEvent.VK_ESCAPE){
try{ct.setText("ESC key pressed");
this.dispose();}catch(Exception excep){System.out.println("Failed to EXIT!");}
}else{
ct.setText("Key not registred");
}
mon.setLocation(monX, 225);
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
Then i tried to separate them and ended up with the following code,
Second Code...
JFrame Half
public class Fgui extends JFrame {
private JPanel jp;
private Icon background = new ImageIcon(getClass().getResource("back2.png"));
private Icon monster = new ImageIcon(getClass().getResource("mol.png"));
protected JLabel mon;
private JLabel backG;
protected int monX = 300;
private int monY = 225;
protected int monDX = 0;
private int monDY = 0;
protected JLabel ct = new JLabel("Change Text");
protected int code;
public Fgui(){
super("Crazy Monster Eating Game");
this.setSize(750,400);
this.setLayout(null);
mon = new JLabel(monster);
backG = new JLabel(background);
KeyL KeyLObj = new KeyL();
this.addKeyListener(KeyLObj);
this.add(mon);
mon.setSize(150,150);
mon.setLocation(monX, 225);
this.add(ct);
ct.setSize(750,20);
ct.setLocation(0,0);
this.add(backG);
backG.setSize(750,400);
backG.setLocation(0,0);
}
}
KeyListener Half
public class KeyL extends Fgui implements KeyListener{
public void keyPressed(KeyEvent e) {
code = e.getKeyCode();
if(code == KeyEvent.VK_LEFT){
monDX = -40;
ct.setText("left key pressed");
monX = monDX+monX;
}
else if(code == KeyEvent.VK_RIGHT){
monDX = 40;
ct.setText("right key pressed");
monX = monDX+monX;
}else if(code == KeyEvent.VK_ESCAPE){
try{ct.setText("ESC key pressed");
this.dispose();}catch(Exception excep){System.out.println("Failed to EXIT!");}
}else{
ct.setText("Key not registred");
}
mon.setLocation(monX, 225);
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}
The Second Code here has two separate classes one is JFrame class the other is for KeyListener class but when i compile it, it does not work. I assume it is the problem with me adding the addKeyListener statement in a wrong way.
KeyL KeyLObj = new KeyL();
this.addKeyListener(KeyLObj);
I tried adding it through the KeyL class but it didn't work either.
The reason i want to do this is because i don't want the code to be cramped all in one class, but separate it into 2 to make it seem more clean. And if i want to add more key events i can just do it in that one class.
The problem you're seeing is pretty simple. Because you make KeyL
a subclass of Fgui
, every time a new KeyL
is constructed, all of the Fgui
initialization code will get run.
So you get to this line:
KeyL KeyLObj = new KeyL();
That creates a new KeyL
, so before that line finishes, a new KeyL
object has to be created. Since a KeyL
is an Fgui
, the Fgui
constructor gets called. And the FGui
constructor eventually gets to that same line, KeyL KeyLObj = new KeyL();
, so the process repeats itself. You can never get past that line, because each new KeyL
needs to make another KeyL
before it can be fully constructed, so the program just keeps making new objects until it runs out of space.
The answer is that there's no reason for KeyL
to be a Fgui
. Make it just implement KeyListener
, and not extend Fgui
. Then, make sure it has access to all the variables it needs to accomplish its task.
Most of your variables should not be fields in the object; they should just be local variables. Anything that doesn't need to exist outside that function, or keep it's value between calls, should be changed to a local variable. It looks like the only two that matter are mon
, ct
, and the Fgui
which you reference with this
. So make those arguments into KeyL
's constructor (as two JLabel
s and a JFrame
), and then call your methods on those.