2013-03-13 65 views
4

我遇到了我的代碼設計問題。我有3個按鈕不在按鈕組中。我想 - 基於選定的按鈕 - 執行操作。現在,該操作需要修改類中的對象。這意味着我不能使用內部類,因爲這不能訪問外部類。如果我可以添加一個事件監聽器到一個按鈕組,這將會容易得多,但是當我看到它時,我將需要每個單選按鈕的事件處理程序,這是正確的嗎?如果不是我可以怎麼做呢?由於3個按鈕的常見操作監聽器

一個簡單的例子

public class Test(){ 
    RadioButton 1 = new RadoButton(); 
    RadioButton 2 = new RadoButton(); 
    RadioButton 3 = new RadoButton(); 
    Object myObject = new Object(); 

    public void clickEvent(){ 
     if(1.isSelected()){ 
      myObject.doOne(); 
     }else if(2.isSelected()){ 
      myObject.doTwo(); 
     }..... 
    } 
} 
+1

這個說法是錯誤的:「我不能使用內部類,因爲它沒有訪問外部」innenene r類不是靜態的。 – gontard 2013-03-13 14:08:25

+2

這是我生命中第一次看到數字作爲名字! – 2013-03-13 14:08:28

+0

@Ali快速輸入:D – Biscuit128 2013-03-13 14:10:28

回答

2

您可以設置相同的監聽所有按鈕。

僞代碼:

radioButton1 = new RadioButton(); 
radioButton2 = new RadioButton(); 
radioButton3 = new RadioButton(); 

listener = new ActionListener() { 
... 
} 


radioButton1.addActionListener(listener); 
radioButton2.addActionListener(listener); 
radioButton3.addActionListener(listener); 
+1

我推薦匿名課程。 – 2013-03-13 14:25:14

+1

@Ali你必須輸入匿名類的主體3次,你不會從單引用中受益。所以匿名類在這個例子中不是很好。 – FazoM 2013-03-13 17:41:20

+0

@fazomisiek爲什麼?實現'ActionListener'的一個匿名類可以處理三個單選按鈕中的每一個的事件。 – 2013-03-13 17:48:09

2

這是說明你如何使用一個內部類

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JRadioButton; 

public class TestInnerClass { 

    JRadioButton radioOne = new JRadioButton(); 
    JRadioButton radioTwo = new JRadioButton(); 
    JRadioButton radioThree = new JRadioButton(); 
    Object myObject = new Object(); 

    public TestInnerClass() { 
     ActionListener myInnerClass = new MyActionListener(); 
     radioOne.addActionListener(myInnerClass); 
     radioTwo.addActionListener(myInnerClass); 
     radioThree.addActionListener(myInnerClass); 
    } 

    private class MyActionListener implements ActionListener { 

     @Override 
     public void actionPerformed(ActionEvent event) { 
      if(radioOne.isSelected()) myObject.toString(); 
      else if(radioTwo.isSelected()) myObject.notify(); 
      else if(radioThree.isSelected()) myObject.getClass().getName(); 
     } 
    } 
} 
  • 注意內部類怎麼也不是一成不變的,在GONTARD的聲明評論,所以對myObject有可見性。最保密的是最安全的。

在這種情況下,讓一個監聽器處理所有事件通常是很好的做法。但是,在其他情況下,您希望您的事件處理更具體到每個組件。例如,在這些情況下,radioThree可能會觸發事件,並且由於這些按鈕不在一個組中,所以radioOne仍處於選定狀態。這個單獨的處理程序只會觸發第一個收音機。而解決這一問題的一種方式是添加檢查源,如:

public void actionPerformed(ActionEvent event) { 
    if(event.getSource() == radioOne && radioOne.isSelected()) 
     myObject.toString(); 
    if(event.getSource() == radioTwo && radioTwo.isSelected()) 
     myObject.notify(); 
    if(event.getSource() == radioThree && radioThree.isSelected()) 
     myObject.getClass().getName(); 
} 

的另一種方式是使用一個監聽每個組件。這就是匿名類是非常方便的:

radioOne.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 
     myObject.doOne(); 
    } 
}); 

我最喜歡的圖案,特別是如果工作是不平凡的,是先創建辦的工作方法,然後從監聽器調用它。我也在SwingUtilities.invokeLater()中封裝了這個調用,以使Swing事件線程無法工作。

public class Test { 

    JRadioButton radioOne = new JRadioButton(); 

    Object myObject = new Object(); 

    private void handleRadioOne() { 
     myObject.toString(); 
     // etc, etc. 
    } 

    public Test() { 

     radioOne.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         handleRadioOne(); 
        } 
       }); 
      } 
     }); 
    } 
} 

這提供了兩個很不錯的功能:

  1. 它封裝了你的行動工作納入允許程序訪問的方法,如果以後需要的
  2. 它確保了該方法的工作一直不亮了Swing事件線程,所以你的圖形用戶界面不會在密集處理過程中掛起