Java, если отмечены несколько флажков? - PullRequest
0 голосов
/ 21 октября 2019

Я создаю простую программу, в которой пользователь может ставить флажки для разных цветов. Если отмечены несколько полей, то это должно показать, каким будет сочетание цветов. Например, синий и желтый отмечены галочкой, а метка - зеленым. У меня 3 проблемы.

  1. Проверка нескольких цветов не смешивается, как в примере выше.
  2. Снятие флажка не приводит к изменению метки.
  3. Когда все они снятыследует вернуться к «Нет выбранных цветов».

class LabDemo extends JFrame implements ActionListener {
    JLabel displayColor = new JLabel("No chosen color");
    JCheckBox blue = new JCheckBox("Blue");
    JCheckBox yellow = new JCheckBox("Yellow");
    JCheckBox red = new JCheckBox("Red");
    JPanel panel = new JPanel();

    public LabDemo() {
        panel.setLayout(new GridLayout(4,1));
        blue.addActionListener(this);
        yellow.addActionListener(this);
        red.addActionListener(this);
        this.add(panel);
        displayColor.setBackground(Color.WHITE);
        panel.add(blue); panel.add(yellow); panel.add(red); panel.add(displayColor);
        setSize(300,300);
        setLocation(100,100);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        if (blue.isSelected()) {
            displayColor.setText("Blue");
            panel.setBackground(Color.BLUE);
        }
        else if (yellow.isSelected()) {
            displayColor.setText("Yellow");
            panel.setBackground(Color.YELLOW);
        }
        else if (red.isSelected()) {
            displayColor.setText("Red");
            panel.setBackground(Color.RED);
        }
        else if (blue.isSelected() && yellow.isSelected()) {
            displayColor.setText("Blue + Yellow = Green");
            panel.setBackground(Color.GREEN);
        }
    }
}

Ответы [ 3 ]

5 голосов
/ 21 октября 2019

Вы никогда не введете в последнем случае (синий и желтый), потому что вы находитесь в if-else, и одно из приведенных выше утверждений будет оценено как истинное до того (только синий)в этом случае). Если дело только в этих четырех, то сначала нужно проверить «синий и желтый».

2 голосов
/ 21 октября 2019

Другая опция: присваивайте каждой отмеченной опции двоичное значение места, суммируйте значения для трех флажков и switch на эту сумму:

switch ((red.isSelected() ?   1 : 0) +
        (green.isSelected() ? 2 : 0) +
        (blue.isSelected() ?  4 : 0))
{
    case 0: // none selected
    case 1: // RED selected
    case 2: // GREEN selected
    case 3: // RED + GREEN
    case 4: //  BLUE
    case 5: // BLUE + RED
    case 6: // BLUE + GREEN
    case 7: // RED + BLUE + GREEN
}
0 голосов
/ 21 октября 2019

Как я уже упоминал в комментарии, лучше использовать красный, зеленый и синий, поскольку вы имеете дело с аддитивными цветами, такими как цвета от световых лучей, а не вычитающие цвета, такие как цвета от красок. Если вы имеете дело с вычитающими цветами, тогда подойдут красный, желтый и синий, но, опять же, здесь не та ситуация.

Другим вариантом решения является использование enum для представления ваших цветов, что-то вроде этого:

import java.awt.Color;

public enum MyColor {
    RED("Red", Color.RED), 
    GREEN("Green", Color.GREEN), 
    BLUE("Blue", Color.BLUE);

    private String name;
    private Color color;

    private MyColor(String name, Color color) {
        this.name = name;
        this.color = color;
    }

    public String getName() {
        return name;
    }

    public Color getColor() {
        return color;
    }
}

Затем мы можем получить массив этих объектов через MyColor.values() и использовать егосоздать JCheckBoxes. Если мы установим флажки в коллекцию, такую ​​как Карта, мы сможем проверить состояние всех из них, когда состояние одного из них изменится:

private Map<MyColor, JCheckBox> colorMap = new EnumMap<>(MyColor.class);

private class CheckListener implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        // initial individual color values
        int r = 0;
        int g = 0;
        int b = 0;

        // iterate through the check boxes, seeing which are selected
        for (MyColor myColor : MyColor.values()) {

            // if selected, extract its colors and add to rgb values
            if (colorMap.get(myColor).isSelected()) {
                r += myColor.getColor().getRed();
                g += myColor.getColor().getGreen();
                b += myColor.getColor().getBlue();
            }
        }

        // let's avoid going beyond the maximum values allowed
        r = Math.min(r, 255);
        g = Math.min(g, 255);
        b = Math.min(b, 255);

        // create a color with the values and set the JPanel
        Color color = new Color(r, g, b);
        colorPanel.setBackground(color);
    }
}

Графический интерфейс может выглядеть так:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EnumMap;
import java.util.Map;
import javax.swing.*;

@SuppressWarnings("serial")
public class ColorExample extends JPanel {
    private JPanel colorPanel = new JPanel();
    private Map<MyColor, JCheckBox> colorMap = new EnumMap<>(MyColor.class);

    public ColorExample() {
        colorPanel.setPreferredSize(new Dimension(400, 300));
        colorPanel.setBackground(Color.BLACK);

        JPanel gridPanel = new JPanel(new GridLayout(1, 0));
        CheckListener checkListener = new CheckListener();
        for (MyColor myColor : MyColor.values()) {
            JCheckBox checkBox = new JCheckBox(myColor.getName());
            checkBox.addActionListener(checkListener);
            colorMap.put(myColor, checkBox);
            gridPanel.add(checkBox);
        }

        setLayout(new BorderLayout());
        add(colorPanel);
        add(gridPanel, BorderLayout.PAGE_END);
    }

    private class CheckListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            // initial individual color values
            int r = 0;
            int g = 0;
            int b = 0;

            // iterate through the check boxes, seeing which are selected
            for (MyColor myColor : MyColor.values()) {

                // if selected, extract its colors and add to rgb values
                if (colorMap.get(myColor).isSelected()) {
                    r += myColor.getColor().getRed();
                    g += myColor.getColor().getGreen();
                    b += myColor.getColor().getBlue();
                }
            }

            // let's avoid going beyond the maximum values allowed
            r = Math.min(r, 255);
            g = Math.min(g, 255);
            b = Math.min(b, 255);

            // create a color with the values and set the JPanel
            Color color = new Color(r, g, b);
            colorPanel.setBackground(color);
        }
    }

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

        JFrame frame = new JFrame("Color Example");
        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());
    }
}
...