4

サンプルプログラムコードで表示するのが最善だと思う次の状況があります。を拡張するJavaクラスがありますJPanel。このクラスには、さらに2つある2つのオブジェクトがありますJPanels。オブジェクトの1つに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

これを解決する 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(); 
  }
}
于 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

マウスが押されたときに 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 に答える
2

あなたは回り道をしているように見えます-最も外側のクラスからすべてをやらないのはなぜですか? 結局のところ、これがリスナーが存在する理由の 1 つです。


    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 に答える
0

リフレクションで遊んでみない限り、Java にはそれを行うための直接的な構文があるとは思いません (もちろんそれは可能ですが、あまりきれいだとは思いません)。

呼び出しを行う時点で、「this」は MouseAdapter の匿名サブクラスを参照します。

最もクリーンな方法は、TheTable でプライベート メソッドを作成し、それを X と呼び、アダプタにその関数を呼び出させることです。

現在、そのメソッド X は TheTable にあるため、それがパネル内にあることを認識していないため、その関数をアクティブにする方法がありません。すべてのテーブルがパネル内にあることが確実な場合は、パネル参照フィールドを Table クラスに追加し、作成時に初期化して (OnePanel のコンストラクターを変更する必要がある場合があります)、 TheTable のメソッド。

最終的に探索しようとしているパネル メソッドが JPanel の一部ではない場合、インターフェイスを作成して渡す必要がある場合があります。

于 2009-01-09T18:29:18.633 に答える