JPanel Action Listener

后端 未结 3 1680
不知归路
不知归路 2021-01-19 03:56

I have a JPanel with a bunch of different check boxes and text fields, I have a button that\'s disabled, and needs to be enabled when specific configurations are setup. What

相关标签:
3条回答
  • 2021-01-19 04:21

    A suggestion could be to derive a class from each of the components you're using and add an ActionListener that bubbles up the Container tree and looks for the first Container that implements a custom interface like this:

    public interface MyCommandProcessor {
      void execute(String actionCommand);
    }
    
    public class MyButton extends JButton {
      public MyButton(string actionCommand) {
        setActionCommand(actionCommand);
        addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent ae) {
            Container traverser = MyButton.this;
            while (traverser != null && !(traverser instanceof MyCommandProcessor))
              traverser = traverser.getParent();
            if (traverser != null)
              ((CommandListener)traverser).execute(ae.getActionCommand());
          }
        });
      }
    }
    
    public class MyApp extends JFrame implements MyCommandListener {
      public MyApp() {
        JPanel panel = new Panel();
        panel.add(new MyButton("MyButton got pressed"));
      }
    
      public void execute(String actionCommand) {
        System.out.println(actionCommand);
      }
    }
    
    0 讨论(0)
  • 2021-01-19 04:26

    You need to create custom component listener. Look here:

    Create a custom event in Java

    Creating Custom Listeners In Java

    http://www.javaworld.com/article/2077333/core-java/mr-happy-object-teaches-custom-events.html

    I do it throw the standard ActionListener Example

    public class MyPanel extends JPanel {
      private final  JComboBox<String> combo1;
      private final JButton btn2;
    
      .......
       //catch the actions of inside components
       btn2.addActionListener(new MyPanelComponentsActionListener());
      ........
    
       //assign actionlistener to panel class
        public void addActionListener(ActionListener l) {
            listenerList.add(ActionListener.class, l);
        }
        public void removeActionListener(ActionListener l) {
            listenerList.remove(ActionListener.class, l);
        }
    
        //handle registered listeners from components used MyPanel class
       protected void fireActionPerformed(ActionEvent event) {
        // Guaranteed to return a non-null array
        Object[] listeners = listenerList.getListenerList();
        ActionEvent e = null;
        // Process the listeners last to first, notifying
        // those that are interested in this event
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==ActionListener.class) {
                // Lazily create the event:
                if (e == null) {
                      String actionCommand = event.getActionCommand();
                      if(actionCommand == null) {
                         actionCommand = "FontChanged";
                      }
                      e = new ActionEvent(FontChooserPanel.this,
                                          ActionEvent.ACTION_PERFORMED,
                                          actionCommand,
                                          event.getWhen(),
                                          event.getModifiers());
                 }
                     // here registered listener executing
                    ((ActionListener)listeners[i+1]).actionPerformed(e); 
                }
            }
        }
    
    //!!! here your event generator
        class MyPanelComponentsActionListener implements ActionListener  {
         public void actionPerformed(ActionEvent e) {
            //do something usefull
            //.....
            fireActionPerformed(e); 
          }
         }
    ....
    }
    
    0 讨论(0)
  • 2021-01-19 04:30

    First off as @Sage mention in his comment a JPanel is rather a container than a component which do action. So you can't attach an ActionListener to a JPanel.

    I figure I can copy and paste my code a bunch of times into every listener in the panel, but that seems like bad coding practice to me.

    You're totally right about that, it's not a good practice at all (see DRY principle). Instead of that you can define just a single ActionListener and attach it to your JCheckBoxes like this:

    final JCheckBox check1 = new JCheckBox("Check1");
    final JCheckBox check2 = new JCheckBox("Check2");
    final JCheckBox check3 = new JCheckBox("Check3");
    
    final JButton buttonToBeEnabled = new JButton("Submit");
    buttonToBeEnabled.setEnabled(false);
    
    ActionListener actionListener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            boolean enable = check1.isSelected() && check3.isSelected();
            buttonToBeEnabled.setEnabled(enable);
        }
    };
    
    check1.addActionListener(actionListener);
    check2.addActionListener(actionListener);
    check3.addActionListener(actionListener);
    

    This means: if check1 and check3 are both selected, then the button must be enabled, otherwise must be disabled. Of course only you know what combination of check boxes should be selected in order to set the button enabled.

    Take a look to How to Use Buttons, Check Boxes, and Radio Buttons tutorial.

    0 讨论(0)
提交回复
热议问题