如何使用JCheckBox启用/禁用JTextField?还是我的代码有什么问题?

时间:2019-01-12 19:47:34

标签: java swing arraylist actionlistener jcheckbox

我是Java编程的新手,我在JTextfield数组旁边有一个JCheckBox数组。

我需要选中一个CheckBox来停用JTextField,但在此方面我没有成功

如何使其与动作侦听器一起使用?

这是我的代码:

public class Checklist_Complete extends JFrame {

    private JLabel      description;
    private JButton     send;
    private JTextField  text[]=new JTextField[10];
    private JCheckBox   cb[]=new JCheckBox[10];

    public Checklist_Complete() {

        setTitle("Activities");
        setSize(500,300);
        setupWidgets();
        setVisible(true);       
    }

    private void setupWidgets() {
        JPanel  pn_center   = new JPanel(new GridLayout(10,1));
        JPanel  pn_west     = new JPanel(new GridLayout(10,1));

        description     = new JLabel("List your activities and uncheck the irrelevant ones");
        send            = new JButton("Send Checklist");

        for (int i=0; i<10; i++) {
            text[i]  = new JTextField();
            cb[i]    = new JCheckBox("", true);
        }

        add(description, BorderLayout.NORTH);
        add(pn_center, BorderLayout.CENTER);
        add(pn_west, BorderLayout.WEST);
        add(send, BorderLayout.SOUTH);

        for (int i=0; i<10; i++){

            pn_center.add(text[i]);
            pn_west.add(cb[i]);
        }
    }

        private void setupEvents() {

            setDefaultCloseOperation(EXIT_ON_CLOSE);

            for (int i=0; i<10; i++) {

                cb[i].addActionListener(new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent event) {
                        if(cb[i].isSelected()){
                            text[i].setEnabled(false);
                        } else{
                            text[i].setEnabled(true);
                        }
                    }
                });
            }
        }

    public static void main(String[] args) {
        new Checklist_Complete();
    }
}

2 个答案:

答案 0 :(得分:1)

这是使用ItemListener的快速解决方案。

 private void setupEvents() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        for (int i=0; i<10; i++) {
            final int finalI = i;
            cb[i].addItemListener(new ItemListener() {
                public void itemStateChanged(ItemEvent e) {
                    text[finalI].setEnabled(e.getStateChange() == ItemEvent.SELECTED);
                }
            });
        }
    }

您也可以使用ActionListener来做到这一点,但是解决方案有点麻烦,而且还不那么优雅。我发布此消息是因为您也可以这样解决问题:

 private void setupEvents() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        for (int i=0; i<10; i++) {
            final int finalI = i;
            cb[i].addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    text[finalI].setEnabled(!text[finalI].isEnabled() && e.getID() == ActionEvent.ACTION_PERFORMED);
                }
            });
        }
    }

答案 1 :(得分:1)

问题:

  • 您永远不会调用setupEvents(),因此永远不会调用此方法中的代码
  • 如果要在内部匿名类中使用本地字段,则需要设置本地字段final

所以:

private void setupEvents() {
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    for (int i=0; i<10; i++) {
        final int finalIndex = i;
        cb[i].addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent event) {
                if(cb[finalIndex].isSelected()){
                    text[finalIndex].setEnabled(false);
                } else{
                    text[finalIndex].setEnabled(true);
                }
            }
        });
    }
}

对于我的洗眼器,我做的事情会有所不同。例如,

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;

@SuppressWarnings("serial")
public class CheckList2 extends JPanel {
    public static final int TEXT_FIELD_COUNT = 10;
    private List<JTextField> fields = new ArrayList<>();
    private JButton sendBtn = new JButton(new SendAction("Send Checklist"));

    public CheckList2() {
        JPanel checkPanel = new JPanel();
        checkPanel.setLayout(new GridLayout(0, 1, 1, 1));
        for (int i = 0; i < TEXT_FIELD_COUNT; i++) {
            JCheckBox checkBox = new JCheckBox("", true);
            // final so can use within item listener
            final JTextField textField = new JTextField(20);
            textField.setEnabled(false);
            fields.add(textField);
            checkBox.addItemListener(itemEvent -> {
                // set textfield enabled based on checkbox state
                textField.setEnabled(itemEvent.getStateChange() == ItemEvent.DESELECTED);
            });
            JPanel rowPanel = new JPanel();
            rowPanel.add(checkBox);
            rowPanel.add(Box.createHorizontalStrut(3));
            rowPanel.add(textField);
            checkPanel.add(rowPanel);
        }

        setLayout(new BorderLayout());
        add(checkPanel, BorderLayout.CENTER);
        add(sendBtn, BorderLayout.PAGE_END);
    }

    private class SendAction extends AbstractAction {
        public SendAction(String name) {
            super(name);
            int mnemonic = name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            for (JTextField jTextField : fields) {
                System.out.println(jTextField.getText());
            }
            System.out.println();
        }
    }

    private static void createAndShowGui() {
        CheckList2 mainPanel = new CheckList2();

        JFrame frame = new JFrame("CheckList2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}