繁体   English   中英

将一些复选框从一个ActionListener转移到另一个ActionListener

[英]transfer some checkboxes from an ActionListener to another ActionListener

我想检查单击按钮b后选择了哪些复选框,但是单击按钮b1后声明了我的复选框

我的意思是,我应该全局声明checkbox[]吗? 我该怎么办?

b1.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent event){
       JCheckBox checkbox[] = new JCheckBox[3];
       checkbox[0] = new JCheckBox("Red");
       checkbox[1] = new JCheckBox("Blue");
       checkbox[2] = new JCheckBox("Green");
    }
});

b.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent e){
       if(checkbox[0].isSelected())
          // do something
       if(checkbox[1].isSelected())
          // do something
       if(checkbox[2].isSelected())
          // do something
    }
});

错误:复选框无法解析为变量

复选框数组对两个侦听器都应可见。 一种选择是作为实例变量。

例如(实际上不会编译,只是一个片段):

   private JCheckBox[] checkboxes;

   void register() {
     s1.addListener(e -> {
        checkboxes = new JCheckBox[3];
        // do the rest
     };

     s2.addListener(e -> {
         if(checkboxes[0].isChecked()) {
         } 
         // ....
      };
    }

但是,这是一个不好的设计,因为checkboxes成员没有完全初始化为使用,这可能会导致NullPointerException 相反,您可能最好在构造函数中初始化数组。

考虑:

   private JCheckBox[] checkboxes;

    SomeClass() {
      checkboxes = new JCheckBox[3];
       // do the rest
     }

     void register() {
       s2.addListener(e -> {
         if(checkboxes[0].isChecked()) {
         } 
         // ....
      };
    }

您可以尝试声明您的JCheckBox[] checkbox = new JCheckBox[3]; 在动作侦听器方法之外。

这是一个例子

import javax.swing.*;
import java.awt.*;

class Scratch {
    private static JCheckBox[] checkbox = null;
    private static int checkBoxNo = 10;

    public static void main(final String[] args) {
        final JButton creteB = new JButton("Create");
        final JButton checkB = new JButton("Check");
        final JSpinner spinner = new JSpinner();
        final JFrame jFrame = new JFrame();

        creteB.addActionListener(actionEvent -> {
            if (checkbox != null) {
                JOptionPane.showMessageDialog(null, "Already created");
                return;
            }
            final int number = (int) spinner.getValue();

            if (number < checkBoxNo) {
                checkBoxNo = number;
            }

            checkbox = new JCheckBox[checkBoxNo];

            for (int i = 0; i < checkBoxNo; ++i) {
                checkbox[i] = new JCheckBox("" + i);
                jFrame.add(checkbox[i]);
            }

            jFrame.pack();
        });

        checkB.addActionListener(e -> {
            if (checkbox == null) {
                JOptionPane.showMessageDialog(null, "First press on creat button");
                return;
            }

            for (int i = 0; i < checkBoxNo; ++i) {
                if (checkbox[i].isSelected()) {
                    checkbox[i].setForeground(Color.RED);
                }
            }
        });

        jFrame.setLayout(new FlowLayout());
        jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        jFrame.add(creteB);
        jFrame.add(checkB);
        jFrame.add(spinner);
        jFrame.pack();
        jFrame.setVisible(true);
    }
}

编辑

在上面的示例中,我还使用了:

  • JOptionPane用于在弹出消息框(或对话框)中向用户显示信息
  • JSpinner用于选择复选框数量
  • Lambda表达式,用于定义动作侦听器功能(仅Java 8中可用)。
new JButton().addActionListener(new ActionListener() {
    public void actionPerformed(final ActionEvent actionEvent) {
        // do something
    }
});

相当于

new JButton().addActionListener(actionEvent -> {
    // do something
});

您不应该在ActionListeneractionPerformed方法内声明Swing组件( JCheckBoxes )。 我想您的按钮是某些面板或框架的一部分吗?

public MyFrame extends JFrame{

   ...
   // somewhere in your container you have those buttons declared
   JButton b1 = new JButton("b1");
   JButton b = new JButton("b"); 
   // add your checkbox declarations here
   JCheckBox checkbox[] = new JCheckBox[3];
   checkbox[0] = new JCheckBox("Red");
   checkbox[1] = new JCheckBox("Blue");
   checkbox[2] = new JCheckBox("Green");

   // if you don't want them visible just yet, then declare them invisible:
   checkbox[0].setVisible(false);
   ..

   // then you declare your listeners:
   b1.addActionListener(new ActionListener(){
     public void actionPerformed(ActionEvent event){
        checkboxes[0].setVisible(true);  // or whatever action you want 
    }
   });

   b.addActionListener(new ActionListener(){
     public void actionPerformed(ActionEvent e){
        if(checkbox[0].isSelected())
        // do something
        if(checkbox[1].isSelected())
        // do something
        if(checkbox[2].isSelected())
        // do something
     }
   });
  ...

}

编辑

让我们暂时搁置“动态UI”的想法。

您具有GUI组件(按钮,InputField,CheckBoxes ...),并且要在这些组件上执行不同的“操作”。 即使用户操作和交互看起来很复杂,您仍然可以保持代码简单。

所有 GUI组件都在同一框架中声明时,您可以在框架的方法中访问它们而不会出现问题。

例如,您可以编写一个方法(在Frame类内部)来处理b按钮的操作:

private void onBClicked(){                             // method inside your frame
   if(this.checkbox[0].isSelected()){                  // here you can access all components from the frame
       String input = this.myTextInputField.getText(); // and handle the user's input
       if(input.equalsIgnoreCase("awesome")){
           checkbox[1].setSelected(true);
       }else{
           this.myTextInputField.setText("Try again");
       } 
       this.repaint();     // this is just a fallback to ensure that Java updates the GUI for your (the "this" is the frame)
   }
}

这样,您可以将所有操作作为简单的方法编写在框架内。 为了执行该方法,您需要声明侦听器:

...
JButton b = new JButton("b");
b.addActionListener(this::onBClicked);  // right after declaring the button, you add the listener

符号

 addActionListener(this::onBClicked);

是的快捷方式

addActionListener(e -> {
   this.onBClicked();
});

这是

addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent event){
       MyFrame.this.onBClicked();
    }
});

因为ActionListener只有一种方法必须实现,所以可以将要直接调用的方法的名称作为参数传递。

这就是所有按钮的操作。 不用担心“全局” /“本地”问题。 只要框架存在,按钮就会存在,按钮就会存在,它们的ActionListeners也将存在,所以只要ActionListeners存在,您就希望能够执行和操作框架的内容。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM