Java — вызов метода объекта, не входящего в область видимости (дочерние элементы родителя)

#java #swing #scope

#java #swing #область видимости

Вопрос:

Возможно, этот вопрос задавался много раз раньше, или я не знаю, что искать, чтобы получить ответ. У меня есть JFrame, который загружается в нескольких JPanels. С чем у меня возникают трудности, так это с обновлением содержимого одной JPanel из другой. Допустим, у меня есть следующее:

 JFrame1.JPanel1.JButtonA
JFrame1.JPanel2.JButtonB
  

При нажатии JButtonA я хочу, чтобы текст JButtonB был изменен. Конечно, это не то, что я хочу сделать, но это простой пример того, чего я хотел бы достичь. Где я ошибаюсь? Как получить ссылку на объект, не превращая все в синглтон?

Комментарии:

1. Не могли бы вы, пожалуйста, предоставить SSCCE ? Всегда лучше обсудить это на основе вашего кода, чем любой абстрактный ответ.

Ответ №1:

Самый простой способ, конечно, запомнить ссылку на JFrame1 при построении JPanel1 :

 JPanel1 p1 = new JPanel1(this);
  

и запомните и используйте это в jPanel1:

 public JPanel1(JFrame1 f1) {
    this.f1 = f1;
}
...
public void actionPerformend(...) {
    f1.getPanel2().getButtonB().setText("A is pressed");
}
  

Но это плохо.

Вместо этого подумайте о том, что на самом деле означает нажатие A (например, паузная игра). Затем создайте PauzeGameEventListener интерфейс, реализованный JPanel2 (например, шахматная доска), и заставьте jPanel1 (например, панель управления игрой) запускать PauzeGameEvent для всех слушателей. Таким образом, когда ваш JPanel3 (например, панель оценки) или другие элементы, отличные от gui (например, AI player), также должны быть осведомлены об этом, вы не засоряете код jPanel1.

Комментарии:

1. 1 хорошее объяснение. Хотя вам придется прочитать его дважды, чтобы получить его 🙂

2. @Boro: 1 Согласен. Удобно, что у всех JComponent есть EventListenerList , и API показывает, как реализовать поддержку такого пользовательского прослушивателя.

3. Я забыл упомянуть, что это шаблон проектирования GoF Observer .