【问题标题】:JPanel Action ListenerJPanel 动作监听器
【发布时间】:2013-12-06 09:45:54
【问题描述】:

我有一个带有一堆不同复选框和文本字段的 JPanel,我有一个禁用的按钮,需要在设置特定配置时启用。 我需要的是在整个 JPanel 上寻找事件的侦听器,只要有任何变化。 我相信我需要一个动作监听器,但我找不到任何东西可以将动作监听器与 JPanel 连接起来

JPanel Window = new JPanel();
Window.addActionListener(new ActionListener(){
//Check if configurations is good
}

我认为我可以将我的代码多次复制并粘贴到面板中的每个侦听器中,但这对我来说似乎是一种糟糕的编码习惯。

【问题讨论】:

  • 具体到您所说的配置。 JPanel 是一个容器,而不是一个执行操作的 Controller 组件。单击按钮是一种类似于将其切换为打开和关闭的操作。单击复选框是一种操作,就像您选择带有刻度线的感兴趣的数据一样。

标签: java swing actionlistener jtextfield jcheckbox


【解决方案1】:

首先@Sage 在他的comment 中提到JPanel 是一个容器而不是一个执行操作的组件。所以你不能将ActionListener 附加到JPanel

我想我可以多次复制并粘贴我的代码到每个 面板中的侦听器,但这对我来说似乎是不好的编码习惯。

您完全正确,这根本不是一个好习惯(请参阅DRY principle)。取而代之的是,您可以只定义一个 ActionListener 并将其附加到您的 JCheckBoxes,如下所示:

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

这意味着:如果check1check3 都被选中,那么按钮必须启用,否则必须禁用。当然,只有您知道应该选择哪种复选框组合才能启用按钮。

看看How to Use Buttons, Check Boxes, and Radio Buttons教程。

【讨论】:

    【解决方案2】:

    一个建议可能是从您正在使用的每个组件中派生一个类,并添加一个 ActionListener,它会在 Container 树中冒泡并查找第一个实现如下自定义接口的 Container:

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

    【讨论】:

      【解决方案3】:

      您需要创建自定义组件侦听器。看这里:

      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

      我这样做会抛出标准的 ActionListener 示例

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

      【讨论】:

        猜你喜欢
        • 2012-06-02
        • 1970-01-01
        • 2021-07-02
        • 2011-06-14
        • 1970-01-01
        • 1970-01-01
        • 2013-12-24
        • 2011-09-26
        • 1970-01-01
        相关资源
        最近更新 更多