2013-04-01 34 views
2

我做了一個JPanel兒童,其中包含一對單選按鈕。無論何時單擊單選按鈕,我都希望從Child生成一個ActionEvent。這個動作事件應該「包含」對實際產生事件的按鈕的引用。Parent JPanel - 如何監聽由一個Child JPanel組件生成的事件?

此子元素將用作另一個JPanel Parent中的組件,該父元素將監聽來自Child的事件,而不是聽各個單選按鈕。

我該怎麼做?

到目前爲止的代碼 -

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class RadioListener extends JPanel implements ActionListener{ 

public static final String id = "id"; 

public RadioListener(){ 

    for(int i = 1; i < 5; i++){ 
     JRadioButton jrb = new JRadioButton(i + "", false); 
     jrb.putClientProperty(id, i); 
     this.add(jrb); 
     jrb.addActionListener(this); 

    } 

} 


public void actionPerformed(ActionEvent e){ 

    JRadioButton jrb = (JRadioButton) e.getSource(); 
    Integer id = (Integer) jrb.getClientProperty(RadioListener.id); 
    System.out.println("id " + id); 

} 


public static void main(String[]args){ 

    JFrame frame = new JFrame("Radio buttons"); 
    frame.getContentPane().setLayout(new FlowLayout()); 
    frame.setSize(400, 100); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.getContentPane().add(new RadioListener()); 
    frame.setVisible(true); 


} 

} 
+0

@MadProgrammer - 這個問題是不同的。這是理論上的。我想修改我的代碼,使其正常工作。我正在嘗試使用您在答案中給出的建議。 –

回答

3

我建議提供組件作爲其他感興趣的各方註冊興趣代理的能力。

這意味着您不需要公開其他組件不應該調用或有權訪問的方法/組件。

你也應該充分利用內部類的聽衆,因爲它們會阻止其他方法曝光別人不應該有訪問

public class ProxyActionListener extends JPanel { 

    public static final String id = "id"; 
    private List<JRadioButton> buttons; 

    public ProxyActionListener() { 

     buttons = new ArrayList<>(25); 
     ActionHandler actionHandler = new ActionHandler(); 

     for (int i = 1; i < 5; i++) { 
      JRadioButton jrb = new JRadioButton(i + "", false); 
      jrb.putClientProperty(id, i); 
      this.add(jrb); 
      jrb.addActionListener(actionHandler); 
      buttons.add(jrb); 

     } 

    } 

    public void addActionListener(ActionListener listener) { 
     for (JRadioButton btn : buttons) { 
      btn.addActionListener(listener); 
     } 
    } 

    public void removeActionListener(ActionListener listener) { 
     for (JRadioButton btn : buttons) { 
      btn.removeActionListener(listener); 
     } 
    } 

    public static void main(String[] args) { 

     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       ProxyActionListener pal = new ProxyActionListener(); 
       pal.addActionListener(new ActionListener() { 
        @Override 
        public void actionPerformed(ActionEvent e) { 
         JRadioButton jrb = (JRadioButton) e.getSource(); 
         Integer id = (Integer) jrb.getClientProperty(ProxyActionListener.id); 
         System.out.println("Proxy- id " + id); 
        } 
       }); 

       JFrame frame = new JFrame("Radio buttons"); 
       frame.getContentPane().setLayout(new FlowLayout()); 
       frame.setSize(400, 100); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.getContentPane().add(pal); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    protected class ActionHandler implements ActionListener { 

     @Override 
     public void actionPerformed(ActionEvent e) { 

      JRadioButton jrb = (JRadioButton) e.getSource(); 
      Integer id = (Integer) jrb.getClientProperty(ProxyActionListener.id); 
      System.out.println("id " + id); 

     } 
    } 
} 
+0

但是,即使設計不好,我的代碼(在答案中)是否會有用? –

+0

我無法理解您的代碼。沒有評論。我不知道你爲什麼這樣做 - ProxyActionListener pal = new ProxyActionListener(); pal.addActionListener(new ActionListener(){ @Override public void ............. –

+0

另一個JPanel如何能夠使用此Radio Button Panel並根據生成的事件執行某些操作? –

0

夠這個解決方案好?

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
public class RadioListener extends JPanel{ 

public static final String id = "id"; 
private ActionListener privateActionListener; 
JRadioButton[] btns = new JRadioButton[5]; 

public RadioListener(){ 

    for(int i = 0; i < btns.length; i++){ 
     JRadioButton jrb = new JRadioButton(i + "", false); 
     jrb.putClientProperty(id, i); 
     btns[i] = jrb; 
     this.add(jrb);  
    } 

} 


public static void main(String[]args){ 

    JFrame frame = new JFrame("Radio buttons"); 
    frame.getContentPane().setLayout(new FlowLayout()); 
    frame.setSize(400, 100); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    AnActionListener an = new AnActionListener(); 
    RadioListener rl = new RadioListener(); 
    rl.setActionListener(an); 
    frame.getContentPane().add(rl); 
    frame.setVisible(true); 


} 


public ActionListener getActionListener() { 
    return privateActionListener; 
} 


public void setActionListener(ActionListener privateActionListener) { 

    this.privateActionListener = privateActionListener; 
    for(int i = 0; i < btns.length; i ++){ 

     btns[i].addActionListener(privateActionListener); 

    } 

} 



} 


class AnActionListener implements ActionListener{ 

public void actionPerformed(ActionEvent e){ 

    JRadioButton jrb = (JRadioButton) e.getSource(); 
    Integer id = (Integer) jrb.getClientProperty(RadioListener.id); 
    System.out.println("id " + id); 

} 

} 
3

要進入MadProgrammer的建議(1+)一步,您可以使用Swing Components固有的PropertyChangeSupport用於此目的:

import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 

import javax.swing.*; 

@SuppressWarnings("serial") 
public class RadioListenerTesterHFOE extends JPanel { 
    private RadioListenerHFOE radioListenerHfoe = new RadioListenerHFOE(); 

    public RadioListenerTesterHFOE() { 
     add(radioListenerHfoe); 
     radioListenerHfoe.addPropertyChangeListener(new PropertyChangeListener() { 

     @Override 
     public void propertyChange(PropertyChangeEvent pcEvt) { 
      if (pcEvt.getPropertyName().equals(RadioListenerHFOE.RADIO)) { 
       System.out.println("Radio Selected: " + pcEvt.getNewValue()); 
      } 
     } 
     }); 
    } 

    private static void createAndShowGui() { 
     RadioListenerTesterHFOE mainPanel = new RadioListenerTesterHFOE(); 

     JFrame frame = new JFrame("RadioListenerTesterHFOE"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

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

class RadioListenerHFOE extends JPanel { 
    private static final String[] LABELS = {"1", "2", "3", "4"}; 
    private static final int GAP = 5; 
    public static final String RADIO = "radio"; 
    private ButtonGroup buttonGroup = new ButtonGroup(); 
    private RadioListenerHandler handler = new RadioListenerHandler(); 

    public RadioListenerHFOE() { 
     setLayout(new GridLayout(1, 0, GAP, 0)); 
     for (String label : LABELS) { 
     JRadioButton radioButton = new JRadioButton(label); 
     radioButton.setActionCommand(label); 
     radioButton.addActionListener(handler); 
     buttonGroup.add(radioButton); 
     add(radioButton); 
     }  
    } 

    private class RadioListenerHandler implements ActionListener { 
     private String actionCommand = null; 

     @Override 
     public void actionPerformed(ActionEvent evt) { 
     setActionCommand(evt.getActionCommand()); 
     } 

     private void setActionCommand(String actionCommand) { 
     String oldValue = this.actionCommand; 
     String newValue = actionCommand; 
     this.actionCommand = newValue; 
     firePropertyChange(RADIO, oldValue, newValue); 
     } 
    } 

} 
+0

但是,我的代碼(在答案中)是否有用,即使它不好設計? –

+0

我很困惑,不能解開d這個代碼。 –

+1

+1我也想過這樣做(誠實;)) – MadProgrammer