javafor-loopif-statementactionlistenerjtogglebutton

Changing color of a button depending on state of some Array elements


I am trying to program a JToggleButton Listener for my GUI. The JToggleButtons with this Listener basicly expand the UI to show more Elements and can close them again which all works like expected. However some of the hidden elements are JTextAreas, which depending on if they are filled or not should give the corresponding JToggleButton a different color. I want to make the button red if none of the JTextAreas are filled, yellow if some but not all are filled and finally green if every JTextArea has some text in it. Previously I had custom Listeners for every button, which worked but was horrible to maintain.

Now my code looks like this:

    ActionListener ExpandListener = new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        JToggleButton button = (JToggleButton) e.getSource();
        i = (int) button.getClientProperty("number");
        y=0;
        for(int f=0;f<i;f++){
            y += ChapterSize[f];
        }
        if(ExpandButtons[i].isSelected()){
           for(int g=0;g<ChapterSize[i];g++){
           Comments[g+y].setVisible(true);
           }
        }else{
           for(int g=0;g<ChapterSize[i];g++){
           Comments[g+y].setVisible(false);
           }
        Boolean GreenFlag = false;
        Boolean YellowFlag = false;
        Boolean RedFlag = false;
        for(int g=0;g<ChapterSize[i];g++){
                if(!Comments[g+y].getText().isEmpty()){
                    GreenFlag = true;
                    YellowFlag = true;
                }else{
                    GreenFlag = false;
                }
                if(Comments[g+y].getText().isEmpty()){
                    RedFlag = true;
                }else{
                    RedFlag = false;
                }
            }
            if(GreenFlag == true){
                ExpandButtons[i].setBackground(Color.GREEN);
                YellowFlag = false;
            }
            if(RedFlag == true)ExpandButtons[i].setBackground(Color.RED);
            if(YellowFlag == true)ExpandButtons[i].setBackground(Color.YELLOW);
            }
          }
        };

It kind of works, but I have some issues. Since I don't know how to put an AND or OR Statement of variable length in the loop for the ColorFlags, only the last JTextArea that gets checked is really relevant for the state of the Booleans. So the Button will stay green even if there are empty TextAreas, as long as its not the last one or all of them.

I hope I'm just thinking into the wrong direction and that there is an easier way to write what I want, but despite hours of searching online I haven't been able to find a solution.


Solution

  • I'm not clear yet on what exact behavior you're trying to elicit. What I do know is that

    For example:

    import java.awt.Color;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.*;
    import javax.swing.event.DocumentEvent;
    import javax.swing.event.DocumentListener;
    import javax.swing.text.JTextComponent;
    
    @SuppressWarnings("serial")
    public class JToggleTest extends JPanel {
        private static final int AL_COUNT = 5;
        private JToggleButton toggleButton = new JToggleButton("Toggle Button");
        private List<JTextComponent> textComps = new ArrayList<>();
    
        public JToggleTest() {
            add(toggleButton);
            for (int i = 0; i < AL_COUNT; i++) {
                JTextArea textArea = new JTextArea(3, 15);
                textArea.getDocument().addDocumentListener(new MyDocListener());
                add(new JScrollPane(textArea));
                textComps.add(textArea);
            }
            toggleButton.setBackground(Color.RED);
        }
    
        private class MyDocListener implements DocumentListener {
    
            @Override
            public void changedUpdate(DocumentEvent e) {
                checkDocs();
            }
    
            @Override
            public void insertUpdate(DocumentEvent e) {
                checkDocs();
            }
    
            @Override
            public void removeUpdate(DocumentEvent e) {
                checkDocs();
            }
    
            private void checkDocs() {
                int count = 0;
                for (JTextComponent textComp : textComps) {
                    if (!textComp.getText().trim().isEmpty()) {
                        count++;
                    }
                }
                System.out.println("count: " + count);
                switch (count) {
                case 0:
                    toggleButton.setBackground(Color.RED);
                    break;
    
                case AL_COUNT:
                    toggleButton.setBackground(Color.GREEN);
                    break;
    
                default:
                    toggleButton.setBackground(Color.YELLOW);
                    break;
                }
            }
        }
    
        private static void createAndShowGui() {
            JFrame frame = new JFrame("JToggleTest");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(new JToggleTest());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(() -> createAndShowGui());
        }
    }