Java 父JPanel-如何侦听子JPanel组件生成的事件?

Java 父JPanel-如何侦听子JPanel组件生成的事件?,java,swing,event-handling,jpanel,Java,Swing,Event Handling,Jpanel,我做了一个JPanel的孩子,里面有几个单选按钮。每当单击单选按钮时,我也希望从子级生成ActionEvent。此操作事件应“包含”对实际生成事件的按钮的引用 此子级将用作另一个JPanel父级中的组件,该父级将侦听来自该子级的事件,而不是侦听单个单选按钮 我该怎么做 迄今为止的守则- import javax.swing.*; import java.awt.*; import java.awt.event.*; public class RadioListener extends JPan

我做了一个JPanel的孩子,里面有几个单选按钮。每当单击单选按钮时,我也希望从子级生成ActionEvent。此操作事件应“包含”对实际生成事件的按钮的引用

此子级将用作另一个JPanel父级中的组件,该父级将侦听来自该子级的事件,而不是侦听单个单选按钮

我该怎么做

迄今为止的守则-

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);


}

}
import javax.swing.*;
导入java.awt.*;
导入java.awt.event.*;
公共类RadioListener扩展JPanel实现ActionListener{
公共静态最终字符串id=“id”;
公共RadioListener(){
对于(int i=1;i<5;i++){
JRadioButton jrb=新的JRadioButton(i+“”,false);
jrb.putClientProperty(id,i);
添加(jrb);
jrb.addActionListener(本);
}
}
已执行的公共无效操作(操作事件e){
JRadioButton jrb=(JRadioButton)e.getSource();
整数id=(整数)jrb.getClientProperty(RadioListener.id);
系统输出打印项次(“id”+id);
}
公共静态void main(字符串[]args){
JFrame=新JFrame(“单选按钮”);
frame.getContentPane().setLayout(新的FlowLayout());
框架。设置尺寸(400100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(新的RadioListener());
frame.setVisible(true);
}
}

这个解决方案足够好吗

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);

}

}
import javax.swing.*;
导入java.awt.*;
导入java.awt.event.*;
公共类RadioListener扩展了JPanel{
公共静态最终字符串id=“id”;
私有ActionListener私有ActionListener;
JRadioButton[]btns=新的JRadioButton[5];
公共RadioListener(){
对于(int i=0;i
我建议提供组件作为其他相关方注册兴趣的代理的功能

这意味着您不需要公开其他组件不应该调用或访问的方法/组件

您还应该为侦听器使用内部类,因为它们将防止暴露其他人无权访问的其他方法

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);

        }
    }
}
公共类ProxyActionListener扩展了JPanel{
公共静态最终字符串id=“id”;
私有列表按钮;
公共ProxyActionListener(){
按钮=新阵列列表(25);
ActionHandler ActionHandler=新的ActionHandler();
对于(int i=1;i<5;i++){
JRadioButton jrb=新的JRadioButton(i+“”,false);
jrb.putClientProperty(id,i);
添加(jrb);
addActionListener(actionHandler);
按钮。添加(jrb);
}
}
public void addActionListener(ActionListener listener){
用于(JRadioButton btn:按钮){
btn.addActionListener(listener);
}
}
公共void removeActionListener(ActionListener listener){
用于(JRadioButton btn:按钮){
btn.removeActionListener(listener);
}
}
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
}
ProxyActionListener pal=新的ProxyActionListener();
pal.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
JRadioButton jrb=(JRadioButton)e.getSource();
整数id=(整数)jrb.getClientProperty(ProxyActionListener.id);
System.out.println(“代理-id”+id);
}
});
JFrame=新JFrame(“单选按钮”);
frame.getContentPane().setLayout(新的FlowLayout());
框架。设置尺寸(400100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(pal);
frame.setVisible(true);
}
});
}
受保护的类ActionHandler实现ActionListener{
@凌驾
已执行的公共无效操作(操作事件e){
JRadioButton jrb=(JRadioButton)e.getSource();
整数id=(整数)jrb.getClientProperty(ProxyActionListener.id);
系统输出打印项次(“id”+id);
}
}
}

要进一步了解程序员的建议(1+),您可以使用Swing组件
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);
      }
   }

}