JPanel 动作监听器

Posted

技术标签:

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

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

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

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

【问题讨论】:

具体到您所说的配置。 JPanel 是一个容器,而不是一个执行操作的 Controller 组件。单击按钮是一种类似于将其切换为打开和关闭的操作。单击复选框是一种操作,就像您选择带有刻度线的感兴趣的数据一样。 【参考方案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); 
      
     
....

【讨论】:

以上是关于JPanel 动作监听器的主要内容,如果未能解决你的问题,请参考以下文章

来自另一个类的 JButton 动作侦听器

通过按JButton在随机JPanel上绘制圆圈

更改了其中一个侦听器适合可见性的 JPanel

第十二周总结

如何避免 Swing 中的无限更新循环?

关于在swing的两个JPanel钟一个事件监听器中修改了数组成员变量内容后,再在另一个事件监听器中获取数组成员变量的值发现仍然是初始化时的值没有获取到在另一个事件监听器对它的修改