Доступ к полям контейнера - PullRequest
1 голос
/ 23 февраля 2011

У меня очень глупый вопрос.

Я использую NetBeans для создания небольшого приложения, и у меня возникла следующая проблема;Мой основной класс называется mainApp и расширяет JFrame, который, в свою очередь, содержит JPanel, называемый drawingBoard, который я также расширяю по различным (и не по теме) причинам.

Ядропроблема в том, что в какой-то момент мне нужно получить доступ к одному из полей mainApp, но из-за способа, которым NetBeans создает экземпляр моего основного класса .. (как анонимный класс), я не могу получить ссылку на контейнер (это мойmainApp).

Что я могу сделать, чтобы получить ссылку на mainApp и установить значение ее поля в drawingBoard?

Ответы [ 3 ]

3 голосов
/ 23 февраля 2011

Если вы расширяете, у вас есть контроль над конструктором. Передайте все необходимые ссылки, добавив их в конструктор (и, конечно, назначив их переменным-членам).

Инъекция зависимости Yay!

1 голос
/ 23 февраля 2011

Вы можете получить ссылку на окно верхнего уровня, используя Window win = SwingUtilities.getWindowAncestor (myComponent);и переход в метод вызывает ссылку на любой компонент, который в конечном итоге содержит окно верхнего уровня.Если ваш основной класс также является вашим JFrame верхнего уровня (вы не инициализируете другие JFrames), то вы можете привести возвращенное 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);
   }
}

изменено по рекомендации свечения:

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 для создания чего-то большего, чем самые простые приложения.

1 голос
/ 23 февраля 2011

Ответ Glowcoder хорош. Другой вариант - сделать mainApp Singleton (если, логически говоря, Singleton)

...