Java JPanel 动作监听器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20129166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 23:21:57  来源:igfitidea点击:

JPanel Action Listener

javaswingactionlistenerjtextfieldjcheckbox

提问by Ronin

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 I need is a listener on the the whole JPanel looking for events, whenever anything changes. I believe I need an action listener but I can't find anything to bridge the action Listener with the JPanel

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

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

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.

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

采纳答案by dic19

First off as @Sage mention in his commenta JPanelis rather a container than a component which do action. So you can't attach an ActionListenerto a JPanel.

首先在他的@Sage提意见一个的JPanel是不是该做动作的组件的容器。所以你不能将ActionListener附加到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 ActionListenerand attach it to your JCheckBoxes like this:

您对此完全正确,这根本不是一个好习惯(请参阅DRY 原则)。取而代之的是,您可以只定义一个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);

This means: if check1and check3are 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.

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

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

查看如何使用按钮、复选框和单选按钮教程。

回答by carlsb3rg

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:

一个建议可能是从您正在使用的每个组件派生一个类,并添加一个 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);
  }
}

回答by Paul Scvortsov

You need to create custom component listener. Look here:

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

Create a custom event in Java

在 Java 中创建自定义事件

Creating Custom Listeners In Java

在 Java 中创建自定义侦听器

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

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

I do it throw the standard ActionListener Example

我这样做会抛出标准的 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); 
      }
     }
....
}