Search code examples
javafor-loopif-statementjbutton

How to make a label print when all 6 buttons = the same status in java


Like the title says I need to make a label print when all 6 buttons = the same status in java. I was given code and am supposed to add onto the bottom to change the label if all the buttons status is green or 0 for the case.

Here is the code:

public class SystemCheck extends JFrame {
    static final int N = 6; // number of buttons
    
    /**
    The main class just calls the constructor
    */
    public static void main(String[] args) {
        new SystemCheck();
    }

    /** label to indicate status */
    JLabel lblStatus;
    /** button to test status */
    JButton btnTest;
    /** array of buttons to display */
    JButton[] btns = new JButton[N];
    /** integer array to control status of each light.
    0= green, 1 = orange, 2 = red */
    int[] status = new int[N];

    /** sets up JFrame and JButtons
    calls inner class ButtonListener.<br>
    The ButtonListener is added to btnTest as well as btns[] */
    SystemCheck() {
        this.setTitle("System Check ...");
        this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        this.setLocationRelativeTo(null);
        JPanel panel = new JPanel(new GridLayout(1,6,3,2));
        panel.setBackground(Color.BLUE);
                    
        ButtonListener bl = new ButtonListener();
        for (int i=0; i < N; i++) {
            btns[i] = new JButton(""+i);
            btns[i].addActionListener(bl);
            setButtons("" + i);
            panel.add(btns[i]);
        }

        JPanel panel2 = new JPanel();
        btnTest = new JButton("TEST");
        btnTest.addActionListener(bl);
        lblStatus = new JLabel("nothing to report");
        lblStatus.setBackground(Color.WHITE);
        lblStatus.setOpaque(true);
        panel2.add(btnTest);
        panel2.add(lblStatus);
        this.add(panel,BorderLayout.NORTH);
        this.add(panel2,BorderLayout.SOUTH);
        this.pack();
        this.setLocationRelativeTo(null);
        this.setVisible(true);
    }

    /** inner class to implement ActionListener */
    private class ButtonListener implements ActionListener {
        
        /** method to handle button clicking.
        Calls: testButtons(), setButtons()
        @param e the actionEvent created when any button is clicked */
        public void actionPerformed (ActionEvent e) {
            if (e.getSource() == btnTest) {
                testButtons();
            } else {
                setButtons(e.getActionCommand());
            }       
        }
    }
    /**
    Purpose: Changes the colours of the buttons based on the value of status[].
            Status[] is incremented each time that that button is clikced.
    Called from: actionPerformed
    @param  cmd The number on the button
    */
    void setButtons(String cmd){
        int n = Integer.parseInt(cmd);
        status[n]++;
        if (status[n] > 2) status[n] = 0;
        switch (status[n]){
            case 0:
                btns[n].setBackground(Color.GREEN);
                break;
            case 1:
                btns[n].setBackground(Color.ORANGE);
                break;
            case 2:
                btns[n].setBackground(Color.RED);
                break;
//          default: 
//              status[n] = 0;
//              btns[n].setBackground(Color.GREEN);
        }       
        // testButtons();
    }
    
    /** TODO: 
     * This is the method that needs to be written to test <br>
    (a) if all the buttons are green (say "All systems go!")<br>
    (b) if there are one or more reds (say "Danger error!")<br>
    The code should be done by checking the value of status.
    Do your best to use a FOR LOOP instead of having to check 6 individual buttons.
    What if there were 200 buttons to check?
    
    Called from: actionPerformed()  */
    void testButtons(){
        boolean ok;
        lblStatus.setText("Waiting ....");
    }//this is the default message

        
        //If all 6 buttons are green display "All Systems Go!"

//This is where I can add in code, this is what I have done.
    void testGreenButtons(){
        int greenButtons = 0;
        for(int i = 0; i < 6; i++) {
           if(btns.equals(status[0])) {
            greenButtons+=1;
                }
           if(greenButtons == 6) {
                lblStatus.setText("All Systems Go!");
           }
      }
   }
}

It says that I need to check the value of status to do this. I have tried everything I can think of however and it is still not working. Thanks for any answers.


Solution

  • You never call the testGreenButtons method.

    public void actionPerformed(ActionEvent e) {
        // ...
        testGreenButtons();
    }
    

    Furthermore, your check for green is wrong. It should be: status[i] == 0

    void testGreenButtons() {
        int greenButtons = 0;
        for (int i = 0; i < 6; i++) {
            if (status[i] == 0) {
                greenButtons += 1;
            }
        }
        if (greenButtons == 6) {
            lblStatus.setText("All Systems Go!");
        }
    }
    

    Try:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class SystemCheck extends JFrame {
        static final int N = 6; // number of buttons
    
        /**
         * The main class just calls the constructor
         */
        public static void main(String[] args) {
            new SystemCheck();
        }
    
        /** label to indicate status */
        JLabel lblStatus;
        /** button to test status */
        JButton btnTest;
        /** array of buttons to display */
        JButton[] btns = new JButton[N];
        /**
         * integer array to control status of each light.
         * 0= green, 1 = orange, 2 = red
         */
        int[] status = new int[N];
    
        /**
         * sets up JFrame and JButtons
         * calls inner class ButtonListener.<br>
         * The ButtonListener is added to btnTest as well as btns[]
         */
        SystemCheck() {
            this.setTitle("System Check ...");
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setLocationRelativeTo(null);
            JPanel panel = new JPanel(new GridLayout(1, 6, 3, 2));
            panel.setBackground(Color.BLUE);
    
            ButtonListener bl = new ButtonListener();
            for (int i = 0; i < N; i++) {
                btns[i] = new JButton("" + i);
                btns[i].addActionListener(bl);
                setButtons("" + i);
                panel.add(btns[i]);
            }
    
            JPanel panel2 = new JPanel();
            btnTest = new JButton("TEST");
            btnTest.addActionListener(bl);
            lblStatus = new JLabel("nothing to report");
            lblStatus.setBackground(Color.WHITE);
            lblStatus.setOpaque(true);
            panel2.add(btnTest);
            panel2.add(lblStatus);
            this.add(panel, BorderLayout.NORTH);
            this.add(panel2, BorderLayout.SOUTH);
            this.pack();
            this.setLocationRelativeTo(null);
            this.setVisible(true);
        }
    
        /** inner class to implement ActionListener */
        private class ButtonListener implements ActionListener {
    
            /**
             * method to handle button clicking.
             * Calls: testButtons(), setButtons()
             * 
             * @param e the actionEvent created when any button is clicked
             */
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == btnTest) {
                    testButtons();
                } else {
                    setButtons(e.getActionCommand());
                }
                testGreenButtons();
            }
        }
    
        /**
         * Purpose: Changes the colours of the buttons based on the value of status[].
         * Status[] is incremented each time that that button is clikced.
         * Called from: actionPerformed
         * 
         * @param cmd The number on the button
         */
        void setButtons(String cmd) {
            int n = Integer.parseInt(cmd);
            status[n]++;
            if (status[n] > 2)
                status[n] = 0;
            switch (status[n]) {
                case 0:
                    btns[n].setBackground(Color.GREEN);
                    break;
                case 1:
                    btns[n].setBackground(Color.ORANGE);
                    break;
                case 2:
                    btns[n].setBackground(Color.RED);
                    break;
                // default:
                // status[n] = 0;
                // btns[n].setBackground(Color.GREEN);
            }
            // testButtons();
        }
    
        /**
         * TODO:
         * This is the method that needs to be written to test <br>
         * (a) if all the buttons are green (say "All systems go!")<br>
         * (b) if there are one or more reds (say "Danger error!")<br>
         * The code should be done by checking the value of status.
         * Do your best to use a FOR LOOP instead of having to check 6 individual
         * buttons.
         * What if there were 200 buttons to check?
         * 
         * Called from: actionPerformed()
         */
        void testButtons() {
            boolean ok;
            lblStatus.setText("Waiting ....");
        }// this is the default message
    
        // If all 6 buttons are green display "All Systems Go!"
    
        // This is where I can add in code, this is what I have done.
        void testGreenButtons() {
            int greenButtons = 0;
            for (int i = 0; i < 6; i++) {
                if (status[i] == 0) {
                    greenButtons += 1;
                }
            }
            if (greenButtons == 6) {
                lblStatus.setText("All Systems Go!");
            }
        }
    }
    

    You should really try to define a Status enum to encapsulate some of the logic:

    enum Status {
        GREEN(Color.GREEN),
        ORANGE(Color.ORANGE),
        RED(Color.RED);
    
        private Color color;
    
        private Status(Color color) {
            this.color = color;
        }
    
        public Color getColor() {
            return color;
        }
    }
    

    Here is a cleaned-up example:

    package org.example;
    
    import java.awt.*;
    import java.awt.event.*;
    import java.util.stream.Stream;
    
    import javax.swing.*;
    
    public class SystemCheck implements Runnable {
        static final int BUTTON_COUNT = 6;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new SystemCheck());
        }
    
        private JLabel lblStatus;
        private JButton btnTest;
        private StatusButton[] btns = new StatusButton[BUTTON_COUNT];
    
        private Container contentPane;
    
        @Override
        public void run() {
            JFrame frame = new JFrame("System Check ...");
            frame.setContentPane(contentPane);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public SystemCheck() {
            contentPane = new JPanel(new BorderLayout());
    
            JPanel buttonPanel = new JPanel(new GridLayout(1, 6, 3, 2));
            buttonPanel.setBackground(Color.BLUE);
    
            ButtonListener bl = new ButtonListener();
            for (int i = 0; i < BUTTON_COUNT; i++) {
                btns[i] = new StatusButton(Integer.toString(i), Status.GREEN);
                btns[i].addActionListener(bl);
                updateButton(Integer.toString(i));
                buttonPanel.add(btns[i]);
            }
    
            JPanel infoPanel = new JPanel();
            btnTest = new JButton("TEST");
            btnTest.addActionListener(bl);
            lblStatus = new JLabel("nothing to report");
            lblStatus.setBackground(Color.WHITE);
            lblStatus.setOpaque(true);
            infoPanel.add(btnTest);
            infoPanel.add(lblStatus);
            contentPane.add(buttonPanel, BorderLayout.NORTH);
            contentPane.add(infoPanel, BorderLayout.SOUTH);
        }
    
        private void updateButton(String cmd) {
            btns[Integer.parseInt(cmd)].incrementStatus().syncColorWithStatus();
        }
    
        private void testButtons() {
            lblStatus.setText("Waiting ....");
        }
    
        private void testGreenButtons() {
            boolean allMatch = Stream.of(btns)
                    .map(StatusButton::getStatus)
                    .allMatch(status -> status == Status.GREEN);
            if (allMatch) {
                lblStatus.setText("All Systems Go!");
            }
        }
    
        private class ButtonListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == btnTest) {
                    testButtons();
                } else {
                    updateButton(e.getActionCommand());
                }
                testGreenButtons();
            }
        }
    
        private class StatusButton extends JButton {
            private Status status;
    
            public StatusButton(String text) {
                this(text, Status.RED);
            }
    
            public StatusButton(String text, Status status) {
                super(text);
                this.status = status;
            }
    
            public StatusButton syncColorWithStatus() {
                this.setBackground(this.status.getColor());
                return this;
            }
    
            public StatusButton incrementStatus() {
                this.status = Status.nextStatus(this.status);
                return this;
            }
    
            public void setStatus(Status status) {
                this.status = status;
            }
    
            public Status getStatus() {
                return status;
            }
        }
    
        private enum Status {
            GREEN(Color.GREEN),
            ORANGE(Color.ORANGE),
            RED(Color.RED);
    
            private Color color;
    
            private Status(Color color) {
                this.color = color;
            }
    
            public Color getColor() {
                return color;
            }
    
            public static Status nextStatus(Status status) {
                switch (status) {
                    case GREEN:
                        return ORANGE;
                    case ORANGE:
                        return RED;
                    case RED:
                        return GREEN;
                }
                return null;
            }
        }
    }
    

    If you want to separate state from display, you can always create an application model. Each time an action is performed, the state gets updated in each method call. At the very end, you can "render" the new state changes:

    package org.example;
    
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.util.*;
    import java.util.List;
    
    public class SystemCheck implements Runnable {
        static final int BUTTON_COUNT = 6;
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new SystemCheck());
        }
    
        private AppModel appModel; // Application state
        private Container contentPane;
    
        @Override
        public void run() {
            JFrame frame = new JFrame("System Check ...");
            frame.setContentPane(contentPane);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public SystemCheck() {
            appModel = new AppModel();
            contentPane = new JPanel(new BorderLayout());
    
            JPanel buttonPanel = new JPanel(new GridLayout(1, 6, 3, 2));
            buttonPanel.setBackground(Color.BLUE);
    
            ButtonListener buttonListener = new ButtonListener();
            for (int i = 0; i < BUTTON_COUNT; i++) {
                JButton btn = new JButton(Integer.toString(i));
                btn.addActionListener(buttonListener);
                appModel.addButton(new StatusButtonModel(btn, Status.ORANGE));
                buttonPanel.add(btn);
            }
    
            JPanel infoPanel = new JPanel();
            JButton btnTest = new JButton("TEST");
            btnTest.addActionListener(buttonListener);
            appModel.setTestButton(new TextButtonModel(btnTest, btnTest.getText()));
            JLabel lblStatus = new JLabel("nothing to report");
            appModel.setStatusLabel(new LabelModel(lblStatus, lblStatus.getText()));
    
            lblStatus.setBackground(Color.WHITE);
            lblStatus.setOpaque(true);
            infoPanel.add(btnTest);
            infoPanel.add(lblStatus);
            contentPane.add(buttonPanel, BorderLayout.NORTH);
            contentPane.add(infoPanel, BorderLayout.SOUTH);
            render();
        }
    
        private void updateButton(String cmd) {
            int index = Integer.parseInt(cmd);
            StatusButtonModel button = appModel.getButton(index);
            button.setStatus(Status.nextStatus(button.getStatus()));
        }
    
        private void testButtons() {
            appModel.getStatusLabel().setValue("Waiting ....");
        }
    
        private void testGreenButtons() {
            boolean allMatch = appModel.getButtons()
                    .stream()
                    .map(StatusButtonModel::getStatus)
                    .allMatch(status -> status == Status.GREEN);
            if (allMatch) {
                appModel.getStatusLabel().setValue("All Systems Go!");
            }
        }
    
        protected void render() {
            appModel.getStatusLabel().getComponentRef().setText(appModel.getStatusLabel().getValue());
            appModel.getButtons().forEach(button -> {
                button.getComponentRef().setBackground(button.getStatus().getColor());
            });
        }
    
        private class ButtonListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (e.getSource() == appModel.getTestButton().getComponentRef()) {
                    testButtons();
                } else {
                    updateButton(e.getActionCommand());
                }
                testGreenButtons();
                render();
            }
        }
    
        private class AppModel {
            private List<StatusButtonModel> buttons;
            private LabelModel statusLabel;
            private TextButtonModel testButton;
    
            public AppModel() {
                this.buttons = new ArrayList<>();
                this.statusLabel = null;
                this.testButton = null;
            }
    
            public void addButton(StatusButtonModel button) {
                this.buttons.add(button);
            }
    
            public StatusButtonModel getButton(int index) {
                return buttons.get(index);
            }
    
            public List<StatusButtonModel> getButtons() {
                return buttons;
            }
    
            public LabelModel getStatusLabel() {
                return statusLabel;
            }
    
            public void setStatusLabel(LabelModel statusLabel) {
                this.statusLabel = statusLabel;
            }
    
            public TextButtonModel getTestButton() {
                return testButton;
            }
    
            public void setTestButton(TextButtonModel testButton) {
                this.testButton = testButton;
            }
        }
    
        private class ComponentModel<T extends JComponent> {
            private T componentRef;
    
            private ComponentModel(T componentRef) {
                this.componentRef = componentRef;
            }
    
            public T getComponentRef() {
                return componentRef;
            }
        }
    
        private class StatusButtonModel extends ComponentModel<JButton> {
            private Status status;
    
            public StatusButtonModel(JButton buttonRef, Status status) {
                super(buttonRef);
                this.status = status;
            }
    
            public Status getStatus() {
                return status;
            }
    
            public void setStatus(Status status) {
                this.status = status;
            }
        }
    
        private class LabelModel extends ComponentModel<JLabel> {
            private String value;
    
            public LabelModel(JLabel labelRef, String value) {
                super(labelRef);
                this.value = value;
            }
    
            public String getValue() {
                return value;
            }
    
            public void setValue(String value) {
                this.value = value;
            }
        }
    
        private class TextButtonModel extends ComponentModel<JButton> {
            private String value;
    
            public TextButtonModel(JButton buttonRef, String value) {
                super(buttonRef);
                this.value = value;
            }
    
            public String getValue() {
                return value;
            }
    
            public void setValue(String value) {
                this.value = value;
            }
        }
    
        private enum Status {
            GREEN(Color.GREEN),
            ORANGE(Color.ORANGE),
            RED(Color.RED);
    
            private Color color;
    
            private Status(Color color) {
                this.color = color;
            }
    
            public Color getColor() {
                return color;
            }
    
            public static Status nextStatus(Status status) {
                switch (status) {
                    case GREEN:
                        return ORANGE;
                    case ORANGE:
                        return RED;
                    case RED:
                        return GREEN;
                }
                return null;
            }
        }
    }