Java JPanel动作侦听器

Java JPanel动作侦听器,java,swing,actionlistener,jtextfield,jcheckbox,Java,Swing,Actionlistener,Jtextfield,Jcheckbox,我有一个JPanel,有一堆不同的复选框和文本字段,我有一个按钮被禁用,需要在设置特定配置时启用。 我需要的是一个整个JPanel的监听器,在任何事情发生变化时寻找事件。 我相信我需要一个动作监听器,但我找不到任何东西来连接动作监听器和JPanel JPanel Window = new JPanel(); Window.addActionListener(new ActionListener(){ //Check if configurations is good } 我想我可以将我的代码复

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

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

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

首先,正如@Sage在他的a中提到的,它是一个容器,而不是一个执行操作的组件。因此,您无法将附加到
JPanel

我想我可以将我的代码复制粘贴到每个 面板中的侦听器,但对我来说,这似乎是糟糕的编码实践

你完全正确,这根本不是一个好的做法(见)。相反,您可以只定义一个
ActionListener
并将其附加到
JCheckBox
es,如下所示:

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);
这意味着:如果同时选择了
check1
check3
,则必须启用该按钮,否则必须禁用该按钮。当然,只有您知道应该选择哪些复选框组合才能启用按钮


请看教程。

建议您从正在使用的每个组件派生一个类,并添加一个ActionListener,以弹出容器树,并查找实现如下自定义接口的第一个容器:

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

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

我用标准的ActionListener 范例

公共类MyPanel扩展了JPanel{
私人最终JComboBox组合1;
私人最终按钮btn2;
.......
//捕捉内部组件的动作
btn2.addActionListener(新的MyPanelComponentsActionListener());
........
//将actionlistener分配给panel类
public void addActionListener(ActionListener l){
添加(ActionListener.class,l);
}
公共void removeActionListener(ActionListener l){
删除(ActionListener.class,l);
}
//从MyPanel类使用的组件处理注册的侦听器
受保护的无效fireActionPerformed(ActionEvent事件){
//保证返回非空数组
Object[]listeners=listenerList.getListenerList();
ActionEvente=null;
//从最后一个到第一个处理侦听器,通知
//那些对这次活动感兴趣的人
for(int i=listeners.length-2;i>=0;i-=2){
if(侦听器[i]==ActionListener.class){
//延迟创建事件:
如果(e==null){
字符串actionCommand=event.getActionCommand();
if(actionCommand==null){
actionCommand=“FontChanged”;
}
e=新操作事件(FontChooserPanel.this,
ActionEvent.ACTION_已执行,
行动司令部,
event.getWhen(),
getModifiers());
}
//这里是正在执行的注册侦听器
((ActionListener)监听器[i+1])。actionPerformed(e);
}
}
}
//!!!这是您的事件生成器
类MyPanelComponentsActionListener实现ActionListener{
已执行的公共无效操作(操作事件e){
//做一些有用的事
//.....
(e)执行的行动;
}
}
....
}

请针对您所说的配置
JPanel
是一个容器,而不是执行操作的
控制器
组件。点击一个按钮就像你把它切换到开和关。单击复选框的操作就像用记号标记选择您感兴趣的数据一样。
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); 
      }
     }
....
}