2

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

这个 Child 将用作另一个 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);


}

}
4

3 回答 3

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

        }
    }
}
于 2013-04-01T23:55:34.703 回答
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);
      }
   }

}
于 2013-04-02T01:07:59.770 回答
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);

}

}
于 2013-04-01T23:51:35.370 回答