Java 访问容器字段
我有一个非常愚蠢的问题要问 我正在使用NetBeans构建一个小应用程序,我有以下问题; 我的主要类名为mainApp,它扩展了一个JFrame,而JFrame又包含一个名为drawingBoard的JPanel,出于各种原因和离题原因,我也对它进行了扩展 核心问题是,在某些时候,我需要访问mainApp的一个字段,但由于NetBeans实例化我的主类的方式……作为匿名类,我无法获得对作为我的mainApp的Container的引用Java 访问容器字段,java,components,containers,parent,anonymous-class,Java,Components,Containers,Parent,Anonymous Class,我有一个非常愚蠢的问题要问 我正在使用NetBeans构建一个小应用程序,我有以下问题; 我的主要类名为mainApp,它扩展了一个JFrame,而JFrame又包含一个名为drawingBoard的JPanel,出于各种原因和离题原因,我也对它进行了扩展 核心问题是,在某些时候,我需要访问mainApp的一个字段,但由于NetBeans实例化我的主类的方式……作为匿名类,我无法获得对作为我的mainApp的Container的引用 如何获取mainApp的引用并在drawingBoard中设置
如何获取mainApp的引用并在drawingBoard中设置其字段的值 如果要扩展,则可以控制构造函数。当然,可以通过将引用添加到构造函数并将其分配给成员变量来传递所需的引用
耶,依赖注入 如果要扩展,则可以控制构造函数。当然,可以通过将引用添加到构造函数并将其分配给成员变量来传递所需的引用
耶,依赖注入 Glowcoder的答案很好。另一个选择是,如果mainApp是单例的,那么从逻辑上讲,Glowcoder的答案是好的。另一个选项是使mainApp成为单例,如果从逻辑上讲,它是单例的您可以使用window win=SwingUtilities.getWindowAncestormyComponent获取顶级窗口的引用;并将顶层窗口最终持有的任何组件的引用传递到方法调用中。如果您的主类也是顶级JFrame,您没有初始化任何其他JFrame,那么您可以将返回的窗口强制转换为顶级类类型并调用其公共方法 例如:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Foo1 {
public static void main(String[] args) {
MainApp mainApp = new MainApp();
mainApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainApp.pack();
mainApp.setLocationRelativeTo(null);
mainApp.setVisible(true);
}
}
class MainApp extends JFrame {
public MainApp() {
getContentPane().add(new DrawingBoard());
}
public void mainAppMethod() {
System.out.println("This is being called from the Main App");
}
}
class DrawingBoard extends JPanel {
public DrawingBoard() {
JButton button = new JButton("Button");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MainApp mainApp = (MainApp) SwingUtilities.getWindowAncestor(DrawingBoard.this);
mainApp.mainAppMethod();
}
});
add(button);
}
}
根据glowcoder的建议修改为:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Foo2 {
public static void main(String[] args) {
MainApp2 mainApp = new MainApp2();
mainApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainApp.pack();
mainApp.setLocationRelativeTo(null);
mainApp.setVisible(true);
}
}
class MainApp2 extends JFrame {
public MainApp2() {
getContentPane().add(new DrawingBoard2(this));
}
public void mainAppMethod() {
System.out.println("This is being called from the Main App");
}
}
class DrawingBoard2 extends JPanel {
private MainApp2 mainApp;
public DrawingBoard2(final MainApp2 mainApp) {
this.mainApp = mainApp;
JButton button = new JButton("Button");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
buttonActonPerformed();
}
});
add(button);
}
private void buttonActonPerformed() {
mainApp.mainAppMethod();
}
}
另一个建议是:既然您正在学习Swing,最好不要使用NetBeans为您生成Swing代码,而是手动编写Swing应用程序。通过这样做并学习教程,您将对Swing的工作原理有更深入、更好的了解,如果您需要使用NetBeans代码生成器来制作最简单的应用程序,它将帮助您。您可以使用window win=SwingUtilities.getWindowAncestormyComponent获取顶级窗口的引用;并将顶层窗口最终持有的任何组件的引用传递到方法调用中。如果您的主类也是顶级JFrame,您没有初始化任何其他JFrame,那么您可以将返回的窗口强制转换为顶级类类型并调用其公共方法 例如:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Foo1 {
public static void main(String[] args) {
MainApp mainApp = new MainApp();
mainApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainApp.pack();
mainApp.setLocationRelativeTo(null);
mainApp.setVisible(true);
}
}
class MainApp extends JFrame {
public MainApp() {
getContentPane().add(new DrawingBoard());
}
public void mainAppMethod() {
System.out.println("This is being called from the Main App");
}
}
class DrawingBoard extends JPanel {
public DrawingBoard() {
JButton button = new JButton("Button");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
MainApp mainApp = (MainApp) SwingUtilities.getWindowAncestor(DrawingBoard.this);
mainApp.mainAppMethod();
}
});
add(button);
}
}
根据glowcoder的建议修改为:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class Foo2 {
public static void main(String[] args) {
MainApp2 mainApp = new MainApp2();
mainApp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainApp.pack();
mainApp.setLocationRelativeTo(null);
mainApp.setVisible(true);
}
}
class MainApp2 extends JFrame {
public MainApp2() {
getContentPane().add(new DrawingBoard2(this));
}
public void mainAppMethod() {
System.out.println("This is being called from the Main App");
}
}
class DrawingBoard2 extends JPanel {
private MainApp2 mainApp;
public DrawingBoard2(final MainApp2 mainApp) {
this.mainApp = mainApp;
JButton button = new JButton("Button");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
buttonActonPerformed();
}
});
add(button);
}
private void buttonActonPerformed() {
mainApp.mainAppMethod();
}
}
另一个建议是:既然您正在学习Swing,最好不要使用NetBeans为您生成Swing代码,而是手动编写Swing应用程序。通过这样做并学习教程,您将对Swing的工作原理有更深入、更好的了解,如果您需要使用NetBeans代码生成器来制作最简单的应用程序,它将帮助您。不……不能这样做。。!目标是在应用程序启动后,用户单击drawingBoard,然后父应用程序的字段才会更新。。!glowcoder的建议仍然适用于您的情况Kono5 1+投票。关键是给JPanel class a MainApp字段并在DrawingBoard构造函数中设置它。然后,你可以在应用程序运行期间的任何时候调用它的方法,包括,尤其是在运行时。没错……我没有想到通过构造函数传递整个主类。它也可以这样工作。不……不能这样做。。!目标是在应用程序启动后,用户单击drawingBoard,然后父应用程序的字段才会更新。。!glowcoder的建议仍然适用于您的情况Kono5 1+投票。关键是给JPanel class a MainApp字段并在DrawingBoard构造函数中设置它。然后,你可以在应用程序运行期间的任何时候调用它的方法,包括,尤其是在运行时。没错……我没有想到通过构造函数传递整个主类。它也可以这样工作。我认为将JFrame设为单例不是一个好主意。正如glowcoder指出的那样,这真的没有必要,因为所需要的只是一个简单的参考。我认为将JFrame设为单例不是一个好主意。真的没有必要,正如glowcoder所指出的,所需要的只是一个简单的参考。就像一个符咒一样工作!但现在你又提出了另一个问题。。!如果这两个类没有分别扩展JFrame和JPanel呢?您不应该使用SwingUtilities,而且似乎只有Glowcoder的解决方案可以工作。。。!还有其他方法吗?正如glowcoder提到的,我也同意,这都是关于引用的——必须有一种方法将一个对象的引用传递给另一个对象,通常这是通过con完成的
structor或setter mutator方法。非常感谢您宝贵的输入!最后,我尝试了Glowcoder的方法,就像你建议的一样,猜猜看!它崩溃了netbeans表单编辑器!试试看!这可能是一个真正的错误!这完全取决于你如何尝试。魔鬼就在细节中,就像一个符咒!但现在你又提出了另一个问题。。!如果这两个类没有分别扩展JFrame和JPanel呢?您不应该使用SwingUtilities,而且似乎只有Glowcoder的解决方案可以工作。。。!还有其他方法吗?正如glowcoder提到的,我也同意,这都是关于引用的-必须有一种方法将一个对象的引用传递给另一个对象,通常这是通过构造函数或setter mutator方法来完成的。非常感谢您宝贵的输入!最后,我尝试了Glowcoder的方法,就像你建议的一样,猜猜看!它崩溃了netbeans表单编辑器!试试看!这可能是一个真正的错误!这完全取决于你如何尝试。魔鬼在细节中。