将 KeyListener 和 JFrame 分成两个不同的 类
Separating KeyListener and JFrame into 2 different classes
我将向您展示两种不同的代码来展示我的要求。
第一个代码工作正常,它包含一个 JFrame 和 KeyListener class 但是我想要的是将它们分开。
下面的第一个代码...
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) {}
}
然后我尝试将它们分开并最终得到以下代码,
第二个密码...
JFrame 一半
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 一半
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) {}
}
这里的第二个代码有两个单独的 classes,一个是 JFrame class 另一个是 KeyListener class 但是当我编译它时,它不起作用。我认为这是我以错误的方式添加 addKeyListener 语句的问题。
KeyL KeyLObj = new KeyL();
this.addKeyListener(KeyLObj);
我尝试通过 KeyL 添加它 class 但它也没有用。
我想这样做的原因是因为我不希望代码全部集中在一个 class 中,而是将它分成 2 个以使其看起来更干净。如果我想添加更多关键事件,我可以在那个 class.
中添加
您遇到的问题很简单。因为你让KeyL
成为Fgui
的子类,所以每次构造一个新的KeyL
,所有的Fgui
初始化代码都会得到运行.
所以你到了这一行:
KeyL KeyLObj = new KeyL();
这会创建一个新的 KeyL
,因此在该行结束之前,必须创建一个新的 KeyL
对象。由于 KeyL
是 Fgui
,因此会调用 Fgui
构造函数。 FGui
构造函数最终到达同一行,KeyL KeyLObj = new KeyL();
,因此该过程会自行重复。你永远无法超越那条线,因为每个新的 KeyL
都需要创建另一个 KeyL
才能完全构建,所以程序只会不断创建新对象,直到它 运行 结束space.
答案是 KeyL
没有理由成为 Fgui
。让它只实现 KeyListener
,而不是扩展 Fgui
。然后,确保它可以访问完成任务所需的所有变量。
大多数变量不应该是对象中的字段;它们应该只是局部变量。任何不需要存在于该函数之外或在调用之间保持其值的东西都应该更改为局部变量。看起来唯一重要的两个是 mon
、ct
和您用 this
引用的 Fgui
。因此,将这些参数放入 KeyL
的构造函数中(作为两个 JLabel
和一个 JFrame
),然后在这些参数上调用你的方法。
我将向您展示两种不同的代码来展示我的要求。 第一个代码工作正常,它包含一个 JFrame 和 KeyListener class 但是我想要的是将它们分开。
下面的第一个代码...
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) {}
}
然后我尝试将它们分开并最终得到以下代码,
第二个密码...
JFrame 一半
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 一半
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) {}
}
这里的第二个代码有两个单独的 classes,一个是 JFrame class 另一个是 KeyListener class 但是当我编译它时,它不起作用。我认为这是我以错误的方式添加 addKeyListener 语句的问题。
KeyL KeyLObj = new KeyL();
this.addKeyListener(KeyLObj);
我尝试通过 KeyL 添加它 class 但它也没有用。
我想这样做的原因是因为我不希望代码全部集中在一个 class 中,而是将它分成 2 个以使其看起来更干净。如果我想添加更多关键事件,我可以在那个 class.
中添加您遇到的问题很简单。因为你让KeyL
成为Fgui
的子类,所以每次构造一个新的KeyL
,所有的Fgui
初始化代码都会得到运行.
所以你到了这一行:
KeyL KeyLObj = new KeyL();
这会创建一个新的 KeyL
,因此在该行结束之前,必须创建一个新的 KeyL
对象。由于 KeyL
是 Fgui
,因此会调用 Fgui
构造函数。 FGui
构造函数最终到达同一行,KeyL KeyLObj = new KeyL();
,因此该过程会自行重复。你永远无法超越那条线,因为每个新的 KeyL
都需要创建另一个 KeyL
才能完全构建,所以程序只会不断创建新对象,直到它 运行 结束space.
答案是 KeyL
没有理由成为 Fgui
。让它只实现 KeyListener
,而不是扩展 Fgui
。然后,确保它可以访问完成任务所需的所有变量。
大多数变量不应该是对象中的字段;它们应该只是局部变量。任何不需要存在于该函数之外或在调用之间保持其值的东西都应该更改为局部变量。看起来唯一重要的两个是 mon
、ct
和您用 this
引用的 Fgui
。因此,将这些参数放入 KeyL
的构造函数中(作为两个 JLabel
和一个 JFrame
),然后在这些参数上调用你的方法。