在 jlabel 中显示选定的 jcheckbox

displaying selected jcheckbox in a jlabel

我有 10 个 jcheckbox,应该只选择 5 个。我已经完成了这个的所有编码,但我不知道如何将选定的 5 显示到 jlabel 中。我试着用这个代码来做:

           JCheckBox check;
           JPanel panel=new JPanel();
           for(int i=0; i<10; i++){
                check=new JCheckBox();
                check.addActionListener(listener);
                check.setName("Select"+i);

                panel.add(check); 
            }

这是listener

ActionListener listener = new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            check = (JCheckBox) e.getSource();
            name=check.getName();
        }
    };

这是应该显示在 jlabel 中的面板

        panel2=new JPanel(new GridLayout(5,1));
        for(int i=0; i<5; i++){
            txtVote=new JLabel(name);
            panel2.add(txtVote);
        }

但是使用这段代码,它不会在 jlabel 上显示任何内容。如果我将 listener 更改为:

ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                check = (JCheckBox) e.getSource();
                txtVote.setText(check.getName());
            }
        };

它只会显示到最后一个标签中。其他 jlabels 将是空白的。请帮忙,非常感谢

编辑

这是可运行的代码

public class JCheckBoxtoLabel{
    JCheckBox check;
    String name;
    JLabel txtVote;

     public JCheckBoxtoLabel() {
            JFrame frame = new JFrame();
            JPanel panel = createPanel();
            JPanel panel2 = panel2();

            frame.setLayout(new GridLayout(1,2));
            frame.add(panel); frame.add(panel2);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setSize(500, 300);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }

        private JPanel createPanel() {
               JPanel panel=new JPanel(new GridLayout(10,1));
               for(int i=0; i<10; i++){
                    check=new JCheckBox();
                    check.addActionListener(listener);
                    check.setName("Select"+i);

                    panel.add(check); 
                }

            return panel;
        }

        private JPanel panel2(){
            JPanel panel2=new JPanel(new GridLayout(5,1));
            for(int i=0; i<5; i++){
                txtVote=new JLabel();
                txtVote.setBorder(BorderFactory.createLineBorder(Color.RED));
                panel2.add(txtVote);
            }
         return panel2;
     }

        ActionListener listener = new ActionListener() {
            @Override   
            public void actionPerformed(ActionEvent e) {
                check = (JCheckBox) e.getSource();
                txtVote.setText(check.getName());
            }
        };

        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    new JCheckBoxtoLabel();
                }
            });
        }
}

问题是 txtVote 只是一个 Jlabel,而您正试图将它用于所有 5 个 Jlabel。由于第五个 jlabel 是最后创建的,因此它是正在使用的。我的建议是您创建一个 arraylist 字段并在 panel12 内将每个标签添加到 arraylist。然后在侦听器内部,它将遍历 arraylist 中的每个 jlabel,检查是否设置了文本,如果设置了文本,则检查下一个,直到找到没有文本的一个,然后将文本设置为那个。目前的问题是,在您的代码中,您永远不会定义当他们取消选中该框时会发生什么。

import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class JCheckBoxtoLabel{
JCheckBox check;
String name;
JLabel txtVote;
ArrayList<JLabel> boxLabels;

public JCheckBoxtoLabel() {
    boxLabels = new ArrayList<JLabel>();

    JFrame frame = new JFrame();
    JPanel panel = createPanel();
    JPanel panel2 = panel2();

    frame.setLayout(new GridLayout(1,2));
    frame.add(panel); frame.add(panel2);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(500, 300);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

private JPanel createPanel() {
    JPanel panel=new JPanel(new GridLayout(10,1));
    for(int i=0; i<10; i++){
        check=new JCheckBox();
        check.addActionListener(listener);
        check.setName("Select"+i);

        panel.add(check); 
    }

    return panel;
}

private JPanel panel2(){
    JPanel panel2=new JPanel(new GridLayout(5,1));
    for(int i=0; i<5; i++){
        txtVote=new JLabel();
        txtVote.setBorder(BorderFactory.createLineBorder(Color.RED));
        panel2.add(txtVote);
        boxLabels.add(txtVote);
    }
    return panel2;
}

ActionListener listener = new ActionListener() {
    @Override   
    public void actionPerformed(ActionEvent e) {
        check = (JCheckBox) e.getSource();
        if(!check.isSelected()){
            for(JLabel label: boxLabels){
                if(label.getText().equals(check.getName())) label.setText("");
            }
        }else{
            for(JLabel label: boxLabels){
                if(label.getText().isEmpty()){
                    label.setText(check.getName());
                    return;
                }
            }
        }
    }
};

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new JCheckBoxtoLabel();
        }
    });
}
}

您的变量 JLabel txtVote 是单个 JLabel 对象,而不是数组。

在您的 panel2() 函数中,您将 5 个新的 JLabel 分配给 txtVote。由于您连续分配 5 个,它每次都会被覆盖,因此它只包含最终的 JLabel。

private JPanel panel2(){
         JPanel panel2=new JPanel(new GridLayout(5,1));
         for(int i=0; i<5; i++){
             txtVote=new JLabel();
             txtVote.setBorder(BorderFactory.createLineBorder(Color.RED));
             panel2.add(txtVote);
         }
         return panel2;
}

因此,当您在操作侦听器中对 voteTxt 调用 getText 时,您只会获得最后的标签文本。

要解决此问题,您需要使 txtVote 成为一个 JLabel 数组,并在您的动作侦听器中对您的 JLabel 进行第二次迭代,并依次调用每个 JLabel 的获取文本。

ActionListener listener = new ActionListener() {
    @Override   
    public void actionPerformed(ActionEvent e) {
        check = (JCheckBox) e.getSource();
        for (int i = 0; i < txtVotes.length; i++) {
            txtVotes[i].getText(check.getName());
        }
    }
};

我不知道你是否意识到或想要,但每个标签都被设置为相同的值,如果你不想要这个,你将需要在某处存储一组检查名称并遍历这些还有。

考虑更改您正在做的事情并在 JList 而不是 JLabel 中显示文本。这可以帮助您整合信息。您还可以给 JCheckBoxes 或 JRadioButtons 和 ItemListener 一次只允许选择 5 个按钮——取消选择当前选择的最旧的按钮。例如:

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

@SuppressWarnings("serial")
public class FiveNames extends JPanel {
    private static final String[] ALL_NAMES = {"Bob", "Bill", "Frank", "Helen", 
            "Erica", "Mickey", "Donald", "Hillary", "Michael", "Peter", "Roger"};
    private static final int ALLOWED_SELECTIONS_COUNT = 5;
    private DefaultListModel<String> displayListModel = new DefaultListModel<>();
    private JList<String> list = new JList<>(displayListModel);

    public FiveNames() {
        JPanel namePanel = new JPanel(new GridLayout(0, 1, 0, 5));
        RButtonItemListener rButtonListener = new RButtonItemListener();
        for (String name : ALL_NAMES) {
            JRadioButton rButton = new JRadioButton(name);
            rButton.setActionCommand(name);
            rButton.addItemListener(rButtonListener);
            namePanel.add(rButton);
        }

        list.setVisibleRowCount(ALLOWED_SELECTIONS_COUNT);
        list.setPrototypeCellValue("                            ");
        list.setBackground(null);

        setLayout(new GridLayout(1, 0));
        add(namePanel);
        add(list);
    }

    // listener to only allow the last 5 radiobuttons to be selected
    private class RButtonItemListener implements ItemListener {
        private List<ButtonModel> buttonModelList = new ArrayList<>();

        @Override
        public void itemStateChanged(ItemEvent e) {
            JRadioButton rBtn = (JRadioButton) e.getSource();
            ButtonModel model = rBtn.getModel();
            if (e.getStateChange() == ItemEvent.SELECTED) {
                buttonModelList.add(model);
                if (buttonModelList.size() > ALLOWED_SELECTIONS_COUNT) {
                    for (int i = 0; i < buttonModelList.size() - ALLOWED_SELECTIONS_COUNT; i++) {
                        ButtonModel removedModel = buttonModelList.remove(0);
                        removedModel.setSelected(false);
                    }
                }
            } else {
                buttonModelList.remove(model);
            }
            displayListModel.clear();
            for (ButtonModel buttonModel : buttonModelList) {
                displayListModel.addElement(buttonModel.getActionCommand());
            }
        }

    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("FiveNames");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new FiveNames());
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

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