2009-11-22 63 views
1

說我有一個擺動GUI,我想聽MouseEvents。你認爲誰應該是Listener類,誰應該負責?什麼是實現它的最佳或首選方式?有什麼意見?我通常是這樣的:聽衆有更好的做法嗎?

public class MyPanel extends JPanel implements MouseListener{ 
    private JTable table; 
    public void foo(){ 
     table.addMouseListener(this); 
    } 
    /* MouseListener */ 
    //Implement MouseListener here. 
} 

有沒有更好的方法?


編輯:謝謝大家的智慧和幫助。我很感激。

+0

我猜測添加'JTable'的鼠標監聽器可能會並不總是做你想做的事。 – 2009-11-22 19:05:29

回答

6

有幾種常見的方法來做事件監聽器(我能想到的唯一一個我在下面的代碼中停留的是靜態內部類)。下面的代碼使用ActionListener,因爲它最簡單,但您可以將該想法應用於任何偵聽器。

請注意,「這個」方法(讓類實現偵聽器)可能導致大量的if/else語句集。我會說這是最糟糕的方式,因爲這一點。我不喜歡有「清算所」的方法有兩個原因:

1)它們很大 2)它很容易在方法內部完成工作,而不是讓每個if/else調用一個方法來完成工作其中,因爲你可以看到,是我在這裏做......哎呀:-)

我也不喜歡匿名的方式,原因有二:

1)你不能輕易地重複使用代碼,以便你可能會發現你有一段時間後重復代碼 2)我發現它破壞了代碼的閱讀(其他人不同意...個人品味)。我認爲每個人都會同意,如果你做了超過5-10行的話,那麼匿名的內部類不是一個好主意(我會說超過2個就太多了)。

這留下了內在和外在的方式。當我正在編寫一個與它正在監聽的GUI緊密關聯的偵聽器時,我會使用外部方法。如果偵聽器不需要作爲類的一部分的信息(成員變量/方法)(本例中爲TestFrame),我會選擇外部類。在下面的示例中,我傳入了「this」,以便外部偵聽器可以訪問GUI ...如果要編寫這樣的代碼,我會將其作爲內部類,因爲它需要來自GUI的某些內容。

所以,我的優先順序是:

  • 內部類(靜態,如果可能的,但如果你正在爲靜態我會去外類)
  • 外部類
  • 匿名內部類(罕見)
  • 有類實現它本身(永遠不會我做到這一點。從來沒有!)

這裏是代碼

import java.awt.FlowLayout; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 


public class Main 
{ 
    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(
      new Runnable() 
      { 
       public void run() 
       { 
        createAndShowGUI(); 
       } 
      }); 
    } 

    private static void createAndShowGUI() 
    { 
     final TestFrame frame; 

     frame = new TestFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setBounds(new Rectangle(10, 10, 300, 300)); 
     frame.init(); 
     frame.setVisible(true); 
    } 
} 

class TestFrame 
    extends JFrame 
    implements ActionListener 
{ 
    private final JButton aBtn; 
    private final JButton bBtn; 

    public TestFrame() 
    { 
     super("Test"); 

     aBtn = new JButton("A"); 
     bBtn = new JButton("B"); 
    } 

    public void init() 
    { 
     setLayout(new FlowLayout()); 
     add(aBtn); 
     add(bBtn); 

     // the class, since it implements ActionListener 
     aBtn.addActionListener(this); 
     bBtn.addActionListener(this); 

     // outer classes 
     aBtn.addActionListener(new OuterAListener(this)); 
     bBtn.addActionListener(new OuterBListener(this)); 

     // inner class 
     aBtn.addActionListener(new InnerAListener()); 
     bBtn.addActionListener(new InnerBListener()); 

     // anonymous classes 
     aBtn.addActionListener(
      new ActionListener() 
      { 
       public void actionPerformed(final ActionEvent e) 
       { 
        System.out.println ("Hi from Anonymous A"); 
       } 
      }); 

     bBtn.addActionListener(
      new ActionListener() 
      { 
       public void actionPerformed(final ActionEvent e) 
       { 
        System.out.println ("Hi from Anonymous B"); 
       } 
      }); 
    } 

    public void actionPerformed(final ActionEvent evt) 
    { 
     final Object source; 

     source = evt.getSource(); 

     if(source == aBtn) 
     { 
      System.out.println ("Hi from this A"); 
     } 
     else if (source == bBtn) 
     { 
      System.out.println ("Hi from this B"); 
     } 
     else 
     { 
      // ??? 
     } 
    } 

    private class InnerAListener 
     implements ActionListener 
    { 
     public void actionPerformed(final ActionEvent e) 
     { 
      System.out.println ("Hi from Inner A"); 
     } 
    } 

    private class InnerBListener 
     implements ActionListener 
    { 
     public void actionPerformed(final ActionEvent e) 
     { 
      System.out.println ("Hi from Inner B"); 
     } 
    } 
} 

class OuterAListener 
    implements ActionListener 
{ 
    private final TestFrame frame; 

    public OuterAListener(final TestFrame f) 
    { 
     frame = f; 
    } 

    public void actionPerformed(final ActionEvent e) 
    { 
     System.out.println ("Hi from Outer A"); 
    } 
} 

class OuterBListener 
    implements ActionListener 
{ 
    private final TestFrame frame; 

    public OuterBListener(final TestFrame f) 
    { 
     frame = f; 
    } 

    public void actionPerformed(final ActionEvent e) 
    { 
     System.out.println ("Hi from Outer B"); 
    } 
} 
2

我建議把聽衆在自己的類,使它可重複使用的,並有顧慮

+0

(另外,請不要擴展'JPanel'(除非你的意思是這樣)。) – 2009-11-22 19:04:43

+0

+ +1,我在下面看到我的例子。 – 2009-11-22 19:27:29

2

瞭解Java的Swing代碼的明確分離。這真的是看到好標準的最佳場所。

在你的情況,我有這樣的:

public class MyPanel extends JTable { 

    public void foo() { 
     addMouseListener(new MouseHandler()); 
    } 

    private class MouseHandler implements MouseListener { 
     ... 
    } 
} 

這樣你的功能明確分工。當你的主類開始實現十五個不同的接口時,你的代碼將變得完全無法維護。

0

匿名類主要用於偵聽器。如果你知道你將有一個特定的監聽器註冊一次,而且它很短,那麼你可以使用匿名類。

0

個人而言,我喜歡將我的GUI與控制器分開。所以我會建議在Controller類中實現監聽器(每個功能GUI都有自己的),並在那裏工作,即使它需要使用if...elseswich...case