Вызов методов «родительского» компонента в Java - PullRequest
4 голосов
/ 09 января 2009

У меня следующая ситуация, которую, я думаю, лучше всего показать в примере программного кода У меня есть класс Java, который расширяет JPanel. В этом классе два объекта, которые еще два JPanels. В одном из объектов JPanel находится объект JTable. Я добавил слушателя к этому JTable, который обнаруживает двойной щелчок. Когда он обнаруживает двойной щелчок, я хочу запустить метод в верхнем классе. Как мне ссылаться на этот метод в Java?

public class TopPanel extends JPanel {

  JPanel OnePanel;
  JPanel TwoPanel;

  public void MethodToFire;

}

public class OnePanel extends JPanel {

  JTable TheTable;

}

public class TheTable extends JTable {

  public TheTable {
    this.addMouseListener(new MouseAdapter(){
      public void mouseClicked(MouseEvent e){
          if (e.getClickCount() == 2){ SYNTAX CALLING THE METHOD IN TopPanel  }
      }
    } );
  }
}

Ответы [ 5 ]

7 голосов
/ 09 января 2009

Один из способов решить эту проблему - использовать композицию вместо наследования. Вы можете передать JPanel в свой подкласс JTable.


public class TopPanel extends JPanel 
{
  private TheTable table;

  public TopPanel()
  {
    table = new TheTable(this);
  }

  public void methodToFire() { }
}

public class TheTable extends JTable 
{
  private TopPanel panel;

  public TheTable(TopPanel panel)
  {
    this.panel = panel;

    this.addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        doThing();
      }
    } );
  }

  private void doThing()
  {
    this.panel.methodToFire(); 
  }
}
4 голосов
/ 09 января 2009

Чтобы получить доступ к методу класса Outer, вам необходимо использовать синтаксис Outer.this.method ().

Таким образом, в этом случае, чтобы получить доступ к методу класса TheTable из слушателя, вы должны использовать TheTable.this.callMethod().

Я предполагаю, что TopPanel добавил к этому TheTable. В этом случае вы можете сделать что-то вроде:

mouseClicked(...) {
   TopTable t = (TopTable)TheTable.this.getParent();
   t.MethodToFire();
}

Это прямой ответ на вопрос, не обязательно «лучший» способ сделать это. Подход с безопасным типом композиции будет лучшим долгосрочным решением.

2 голосов
/ 09 января 2009

Вы можете сделать так, чтобы ваш TheTable запускал событие при нажатии мыши, которое ваша TopPanel могла бы прослушивать. Преимущество этого состоит в том, что классы Table и Panel не зависят друг от друга.

Код немного сложнее, но разделение может стоить.

public class TopPanel extends JPanel 
{
  private TheTable table;

  public TopPanel()
  {
    table = new TheTable(this);
    table.addTheTableListener(new TheTableListener() {
      public void tableSelected() {  // or tableSelected(TableSelectionEvent e) if you want to make a TableSelectionEvent
        methodToFire();
      }
    });
  }

  public void methodToFire() { }
}

public class TheTable extends JTable 
{
  private TopPanel panel;
  private EventListenerList listeners;

  public TheTable(TopPanel panel)
  {
    this.panel = panel;
    listeners = new EventListenerList();

    this.addMouseListener(new MouseAdapter() {
      public void mouseClicked(MouseEvent e) {
        fireTableSelected();
      }
    } );
  }

  public void addTheTableListener(TheTableListener l) {
    listeners.add(l);
  }

  // also write removeListener

  private void fireTableSelected()
  {
    for (TheTableListener l : listeners) {
      l.tableSelected(); 
  }
}

public interface TheTableListener extends EventListener
{
    public void tableSelected();
}
2 голосов
/ 09 января 2009

Похоже, вы идете круговым путем - почему бы просто не сделать все из внешнего класса? Это одна из причин, по которой слушатели существуют, в конце концов:


    public class TopPanel {
        public TopPanel() {
            // Construct everything here
            OnePanel.TheTable.addMouseListener(new MouseAdapter(){
              public void mouseClicked(MouseEvent e){
                 if (e.getClickCount() == 2){ MethodToFire }
              }
              } );

        }

    }

0 голосов
/ 09 января 2009

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

В момент, когда вы хотите сделать вызов, ваше «this» относится к анонимному подклассу MouseAdapter.

Самый чистый подход может состоять в том, чтобы создать закрытый метод, назовем его X в TheTable, и чтобы адаптер вызывал эту функцию.

Теперь, поскольку этот метод X находится в TheTable, он не знает, что находится внутри панели, поэтому у него нет никакого способа активировать эту функцию. Если вы уверены, что каждая таблица находится внутри панели, вы можете добавить поле ссылки на панель в свой класс Table, инициализировать его при его создании (вам может потребоваться изменить конструктор в OnePanel), а затем выполнить вызов из метод в таблице.

Если метод панели, который вы в конечном итоге пытаетесь исследовать, не является частью JPanel, вам может потребоваться создать и передать интерфейсы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...