4

我认为最好在示例程序代码中显示以下情况。我有一个扩展的 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  }
      }
    } );
  }
}
4

5 回答 5

7

解决这个问题的一种方法是使用组合而不是继承。您可以将 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(); 
  }
}
于 2009-01-09T18:29:11.410 回答
5

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

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

我认为它TopPanel已经添加了TheTable. 在这种情况下,您可以执行以下操作:

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

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

于 2009-01-09T18:28:55.747 回答
2

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


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

        }

    }

于 2009-01-09T18:34:12.240 回答
2

您可以让 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();
}
于 2009-01-09T18:47:19.127 回答
0

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

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

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

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

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

于 2009-01-09T18:29:18.633 回答