这就是我的代码在开头的样子:https://gist.github.com/anonymous/8270001
现在,我将ActionListener
删除为单独的类:https://gist.github.com/anonymous/8257038
该程序应该给我一个小UI,但它只是在没有任何UI弹出或错误的情况下继续运行。
有人告诉我这个:
在GUI类构造函数中,您正在创建一个新的
nupuVajutus
对象,但由于nupuVajutus
扩展了GUI类,因此在创建nupuVajutus
时,您本身也在调用GUI默认情况下类构造函数,从而创建一个无限循环
如果这确实是问题所在,那么我不得不说我不是那么好并且可以使用一些帮助让这个程序与分离的类一起工作。
答案 0 :(得分:3)
你确实已经得到了答案,虽然你所拥有的不是无限循环,而是无限递归,最终会导致StackOverflowError。
以下是发生的事情:
new GUI()
来电new nupuVajutus()
。这通过调用其构造函数创建一个新的nupuVajutus
对象。由于nupuVajutus
扩展了GUI
,这意味着nupuVajutus
对象是具有附加功能的GUI
对象。因此,因为它是GUI
对象,所以需要调用GUI
构造函数。 nupuVajutus
构造函数没有显式调用super
构造函数,因此它在执行之前隐式调用GUI()
(无参数)构造函数。在对GUI()
构造函数的新调用中,遇到了另一个new nupuVajutus()
调用,依此类推, ad infinitum ...
在我看来,您需要围绕面向对象编程进行更多研究,特别是子类,继承,对象实例和封装等主题。有plenty of resources available to help you。
将ActionListener解压缩到单独的文件后,您不应该将其更改为扩展GUI。这扩展了类(就像蓝图)而不是实例(这就像使用该蓝图构建的东西) - 记住:你可以创建一个类的多个实例。
以前," nupuVajutus" ActionListener是一个内部类,因此它可以访问所有封闭的类'领域和方法。现在它不再是一个内部类,它需要传递一个GUI实例的引用,以便它可以访问它的方法。像这样:
public class NupuVajutus implements ActionListener {
private final GUI gui;
public NupuVajutus(GUI gui) {
this.gui = gui;
}
public void actionPerformed(ActionEvent e) {
// The GUI instance can now be accessed through the gui field, for example:
gui.something();
// ...
}
}
在GUI()
构造函数中:
NupuVajutus nV = new NupuVajutus(this);
老实说,将ActionListener保持为内部类是没有错的。如果您永远不会在GUI类之外使用该类,那么最好将它保留为内部类。
答案 1 :(得分:2)
你在做什么扩展GUI类。 不然后分享相同字段假设您的GUI类中有一个字段field
public class GUI {
String field = "Hello";
}
仅仅因为您的监听器类extends GUI
并不意味着他们将共享完全相同的field
对象。我认为这就是你认为应该发生的事情
public class Listener extends GUI implements ActionListener {
public void actionPerformed(ActionEvent e) {
field = "World";
}
}
上述内容与field
中的GUI
无关。如果您这样做,则需要以行GUI.field = "World";
之类的静态方式访问。以上也是导致无限循环的原因,因为您需要在Listener
类中实例化GUI
。这不是一个很好的练习或设计。
Listener
类中的构造函数,并使用这些值在GUI类中实例化它。运行此示例以查看我正在谈论的内容。我有一个MyListener
类,我将Jlabel
传递给GUI类中的JLabel
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class FieldTest {
private JLabel label = new JLabel(" ");
private JButton button = new JButton("Set Text");
public FieldTest() {
MyListener listener = new MyListener(label);
button.addActionListener(listener);
JFrame frame = new JFrame();
frame.add(label, BorderLayout.CENTER);
frame.add(button, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new FieldTest();
}
});
}
}
class MyListener implements ActionListener {
JLabel label;
public MyListener(JLabel label) {
this.label = label;
}
@Override
public void actionPerformed(ActionEvent arg0) {
label.setText("Hello, FieldTest!");
}
}