访问容器字段

发布于 2024-10-18 21:47:17 字数 385 浏览 1 评论 0原文

我有一个非常愚蠢的问题要问。

我正在使用 NetBeans 构建一个小型应用程序,但遇到以下问题; 我的主类名为 mainApp ,它扩展了一个 JFrame ,它又包含一个名为 drawingBoardJPanel ,我也由于各种(和离题)原因而扩展。

核心问题是,在某些时候我需要访问 mainApp 的字段之一,但由于 NetBeans 实例化我的主类的方式。 (作为匿名类)我无法获取对容器(即我的 mainApp)的引用。

我该如何获取 mainApp 的引用并在 drawingBoard 中设置其字段的值?

I've got a very silly question to ask.

I'm using NetBeans to built a small app and I'm having the following problem;
My main class is called mainApp and is extending a JFrame which in turn contains a JPanel called drawingBoard which I also extend for various (and off-topic) reasons..

The core problem is that at some point I need to access one of the fields of the mainApp but due to the way NetBeans instantiates my main class..(as anonymous class) I can't get a reference to the container(that is my mainApp).

What can I do to get a reference of mainApp and set the value of its field within drawingBoard?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

生来就爱笑 2024-10-25 21:47:17

如果要扩展,您可以控制构造函数。通过将它们添加到构造函数(当然,并将它们分配给成员变量)来传递您需要的任何引用。

耶依赖注入!

If you're extending, you have control over the constructor. Pass in whatever references you need by adding them to the constructor (and assigning them to member variables, of course.)

Yay dependency injection!

东走西顾 2024-10-25 21:47:17

您可以使用 Window win = SwingUtilities.getWindowAncestor(myComponent); 获取对顶级窗口的引用。并将对顶级窗口最终保存的任何组件的引用传递给方法调用。如果您的主类也是您的顶级 JFrame(您没有初始化任何其他 JFrame),那么您可以将返回的 Window 转换为您的顶级类类型并调用其公共方法。

例如:

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 代码生成器来制作最简单的应用程序以外的任何内容,它将为您提供帮助。

You can get a reference to the top level window by using Window win = SwingUtilities.getWindowAncestor(myComponent); and passing into the method call a refrence to any component that the top level window ultimately holds. If your main class is also your top level JFrame (you're not initializing any other JFrames), then you can cast the returned Window to your top level class type and call its public methods.

For example:

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);
   }
}

altered to be done by glowcoder's recommendation:

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();

   }
}

Another recommendation: since you're learning Swing, you're far better off not using NetBeans to generate Swing code for you but rather to code your Swing apps by hand. By doing this and studying the tutorials, you'll gain a far deeper and better understanding of just how Swing works, and it will help you should you need to use the NetBeans code generator to make anything more than the most simple of apps.

丶情人眼里出诗心の 2024-10-25 21:47:17

Glowcoder 的回答很好。另一种选择是使 mainApp 成为单例(如果从逻辑上讲,它是单例)

Glowcoder's answer is good. The other option is to make mainApp a Singleton (if it is, logically speaking, a Singleton)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文