【问题标题】:Calling methods of "parent" component in JavaJava中调用“父”组件的方法
【发布时间】:2009-01-09 18:19:36
【问题描述】:

我认为最好在示例程序代码中显示以下情况。我有一个扩展JPanel 的Java 类。在这个类中有两个对象,它们是另外两个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  }
      }
    } );
  }
}

【问题讨论】:

  • 我在这里看不到 TopPanel 与 TheTable 的关系...尽管我猜接受的答案会告诉您如何关联它...

标签: java class methods


【解决方案1】:

解决此问题的一种方法是使用组合而不是继承。您可以将 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(); 
  }
}

【讨论】:

  • 这绝对是解决此问题的更安全/通用的方法。如我所述,使用 getParent() 假设 TheTable 将始终添加到 TopPanel。
  • 总是更喜欢组合而不是继承,只要它不会真正让你的代码保持干燥
【解决方案2】:

要访问 Outer 类的方法,需要使用 Outer.this.method() 的语法。

因此,在这种情况下,要从侦听器访问“TheTable”类的方法,您应该使用TheTable.this.callMethod()

我假设TopPanel 已将TheTable 添加到其中。在这种情况下,您可以执行以下操作:

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

这是对问题的直接回答,不一定是“最佳”方法。类型安全的组合方法将是更好的长期解决方案。

【讨论】:

    【解决方案3】:

    看来你是在绕道而行——为什么不从最外面的班级做所有事情呢?毕竟,这是听众存在的原因之一:

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

    【讨论】:

      【解决方案4】:

      您可以让 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();
      }
      

      【讨论】:

        【解决方案5】:

        我不认为 Java 有直接的语法来做到这一点,除非你开始使用反射(这当然是可能的,但我认为它不是很干净)。

        在您要拨打电话的地方,您的“this”指的是 MouseAdapter 的匿名子类。

        最简洁的方法可能是在 TheTable 中创建一个私有方法,我们称之为 X,然后让适配器调用该函数。

        现在,因为方法 X 在 TheTable 中,所以它不知道它在面板内,因此它没有任何方法来激活该功能。如果您确定每个表都在一个面板内,那么您可以将一个面板引用字段添加到您的 Table 类,在创建时对其进行初始化(您可能需要修改 OnePanel 上的构造函数),然后从TheTable 中的方法。

        如果您最终尝试探索的面板方法不是 JPanel 的一部分,您可能需要创建和传递接口。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-02-22
          • 2017-11-24
          • 1970-01-01
          • 2016-12-08
          • 2020-06-15
          • 2021-09-24
          • 2018-07-20
          相关资源
          最近更新 更多