Calling methods of “parent” component in Java

前端 未结 5 1072
庸人自扰
庸人自扰 2020-12-10 08:46

I have the following situation I think would be best to show in sample program code. I have a Java class that extends JPanel. In this class are two objects wh

相关标签:
5条回答
  • 2020-12-10 09:21

    To access a method on the Outer class, you need to use the syntax of Outer.this.method().

    So in this case, to access a method on the "TheTable" class from the listener, you should use TheTable.this.callMethod().

    I assume that TopPanel has added to it the TheTable. In this case, you could do something like:

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

    This is a direct answer to the question, not necessarily the "best" way to do it. A type-safe composition approach would be a better long-term solution.

    0 讨论(0)
  • 2020-12-10 09:24

    You could make your TheTable fire an event when the mouse is pressed, which your TopPanel could listen for. This has the benefit of not making the Table and Panel classes both dependent on each other.

    The code is a little more involved, but the decoupling may be worth it.

    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();
    }
    
    0 讨论(0)
  • 2020-12-10 09:35

    Seems like you're going a round-about way - why not just do everything from the outermost class? This is one reason listeners exist, after all:

    
        public class TopPanel {
            public TopPanel() {
                // Construct everything here
                OnePanel.TheTable.addMouseListener(new MouseAdapter(){
                  public void mouseClicked(MouseEvent e){
                     if (e.getClickCount() == 2){ MethodToFire }
                  }
                  } );
    
            }
    
        }
    
    
    0 讨论(0)
  • 2020-12-10 09:40

    One way to solve this is to use composition instead of inheritance. You could pass the JPanel into your subclass of the 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(); 
      }
    }
    
    0 讨论(0)
  • 2020-12-10 09:40

    I don't think that Java has a direct syntax for doing that, unless you start playing with reflection (which is of course possible, but I don't consider it very clean).

    At the point where you want to make the call, your "this" refers to an anonymous subclass of MouseAdapter.

    The cleanest approach may be to create a private method, let's call it X, in TheTable, and have the adapter call that function.

    Now, because that method X is in the TheTable, it doesn't know that it is inside a panel so it doesn't have any way of activating that function. If you are sure that every table is inside a panel, then you can add a panel reference field to your Table class, initialize it when it is created (you may need to modify the constructor on OnePanel), and then make the call from the method in TheTable.

    If the panel method you are ultimately trying to explore not part of JPanel, you may need to create and pass interfaces.

    0 讨论(0)
提交回复
热议问题