JTextArea DocumentListener Issue

55 Views Asked by At

Validation of jTextAreaName

The following Code creates some jTextAreaName with GridBagconstraints. My issues is that I try to validate text in jTextAreaName with a DocumentListener. However it validates just the last jTextAreaName. Not all of them (see the pic above). I think it depends on the GridBagConstraints. But I don´t know how I could solve this issue.

Do you have any hints what should I Change?

Thanks in advance.

public class GridPanel extends JPanel {

private String[] COLUMNS = {"Name", "Frame 1", "Frame 2", "Frame 3", "Frame 4", "Frame 5",
        "Frame 6", "Frame 7", "Frame 8", "Frame 9", "Frame 10", "Total Sum"};

private JTextArea jTextAreaName;
public JTextArea jTextAreaTotalSum;
private JLabel labelName;
private JLabel labelFrame;
private JLabel labelSum;
private static String pattern = "[A-Za-z]*";
public static List<JTextArea> jTextAreas = new ArrayList<>();

public GridPanel(int numPlayers) {
    setLayout(new BorderLayout());
    createGrid(numPlayers);
}


public void createGrid(int numPlayers) {

    setLayout(new GridBagLayout());

    for (int y = 1; y <= numPlayers; y++) {

        createHeader();

        jTextAreaName = new JTextArea(2, 8);
        jTextAreaName.setEditable(true);
        addDocumentListener(jTextAreaName);

        add(jTextAreaName, GridBag.constraints(0, y, 1, 1));

        for (int i = 1; i <= 9; i++) {
            add(new BowlingFramePanel(2), GridBag.constraints(i, y, 1, 1));
        }
        add(new BowlingFramePanel(3), GridBag.constraints(10, y, 1, 1));

        jTextAreaTotalSum = new JTextArea(2, 8);
        jTextAreaTotalSum.setEditable(false);

        add(jTextAreaTotalSum, GridBag.constraints(11, y, 1, 1));
    }

}

private void addDocumentListener(JTextArea jTextArea) {
    jTextArea.getDocument().addDocumentListener(new DocumentListener() {
        @Override
        public void insertUpdate(DocumentEvent e) {
            validateInputName();
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            validateInputName();
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            validateInputName();
        }
    });
}

private void validateInputName() {

    jTextAreas.add(jTextAreaName);

    for (JTextArea jTextArea : jTextAreas) {

        String text = jTextArea.getText();
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(text);

        if (m.matches()) {
            jTextArea.setBackground(Color.GREEN);
            ifTextAreaIsEmptySetBackgroundColorWhite(jTextArea, text);
        } else {
            jTextArea.setBackground(Color.RED);
            ifTextAreaIsEmptySetBackgroundColorWhite(jTextArea, text);
        }
    }
}

private void ifTextAreaIsEmptySetBackgroundColorWhite(JTextArea jTextArea, String text) {
    if (text.isEmpty()) {
        jTextArea.setBackground(Color.WHITE);
    }
}

private void createHeader() {
    labelName = new JLabel(COLUMNS[0]);
    labelName.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));

    add(labelName, GridBag.constraints(0, 0, 1, 1));

    for (int x = 1; x <= 10; x++) {

        labelFrame = new JLabel(" " + "Frame " + Integer.toString(x));
        labelFrame.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));

        add(labelFrame, GridBag.constraints(x, 0, 1, 1));
    }

    labelSum = new JLabel(" " + COLUMNS[11]);
    labelSum.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
    add(labelSum, GridBag.constraints(11, 0, 1, 1));


}}
2

There are 2 best solutions below

0
keuleJ On BEST ANSWER

I think you should add the JTexteAreas directly to the List after creating them. Not in the DocumentListener:

public class GridPanel extends JPanel {

private String[] COLUMNS = {"Name", "Frame 1", "Frame 2", "Frame 3", "Frame 4", "Frame 5",
        "Frame 6", "Frame 7", "Frame 8", "Frame 9", "Frame 10", "Total Sum"};

private JTextArea jTextAreaName;
public JTextArea jTextAreaTotalSum;
private JLabel labelName;
private JLabel labelFrame;
private JLabel labelSum;
private static String pattern = "[A-Za-z]*";
public static List<JTextArea> jTextAreas = new ArrayList<>();

public GridPanel(int numPlayers) {
    setLayout(new BorderLayout());
    createGrid(numPlayers);
}


public void createGrid(int numPlayers) {

    setLayout(new GridBagLayout());

    for (int y = 1; y <= numPlayers; y++) {

        createHeader();

        jTextAreaName = new JTextArea(2, 8);
        jTextAreaName.setEditable(true);
        addDocumentListener(jTextAreaName);

        add(jTextAreaName, GridBag.constraints(0, y, 1, 1));

        for (int i = 1; i <= 9; i++) {
            add(new BowlingFramePanel(2), GridBag.constraints(i, y, 1, 1));
        }
        add(new BowlingFramePanel(3), GridBag.constraints(10, y, 1, 1));

        jTextAreaTotalSum = new JTextArea(2, 8);
        jTextAreaTotalSum.setEditable(false);

        add(jTextAreaTotalSum, GridBag.constraints(11, y, 1, 1));
        jTextAreas.add(jTextAreaName);
    }

}

private void addDocumentListener(JTextArea jTextArea) {
    jTextArea.getDocument().addDocumentListener(new DocumentListener() {
        @Override
        public void insertUpdate(DocumentEvent e) {
            validateInputName();
        }

        @Override
        public void removeUpdate(DocumentEvent e) {
            validateInputName();
        }

        @Override
        public void changedUpdate(DocumentEvent e) {
            validateInputName();
        }
    });
}

private void validateInputName() {
    for (JTextArea jTextArea : jTextAreas) {

        String text = jTextArea.getText();
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(text);

        if (m.matches()) {
            jTextArea.setBackground(Color.GREEN);
            ifTextAreaIsEmptySetBackgroundColorWhite(jTextArea, text);
        } else {
            jTextArea.setBackground(Color.RED);
            ifTextAreaIsEmptySetBackgroundColorWhite(jTextArea, text);
        }
    }
}

private void ifTextAreaIsEmptySetBackgroundColorWhite(JTextArea jTextArea, String text) {
    if (text.isEmpty()) {
        jTextArea.setBackground(Color.WHITE);
    }
}

private void createHeader() {
    labelName = new JLabel(COLUMNS[0]);
    labelName.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));

    add(labelName, GridBag.constraints(0, 0, 1, 1));

    for (int x = 1; x <= 10; x++) {

        labelFrame = new JLabel(" " + "Frame " + Integer.toString(x));
        labelFrame.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));

        add(labelFrame, GridBag.constraints(x, 0, 1, 1));
    }

    labelSum = new JLabel(" " + COLUMNS[11]);
    labelSum.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
    add(labelSum, GridBag.constraints(11, 0, 1, 1));


}}
0
tommybee On

You have the same object used in the for loop.

for (int y = 1; y <= numPlayers; y++) {
    ...
    jTextAreaName = new JTextArea(2, 8);

The jTextAreaName is still the same reference so that's why just only last jtextarea is created.

You need to have enough JTextArea objects then the numPlayers variables.

One possible option for your createGrid method might be as follow

public void createGrid(int numPlayers) {

    setLayout(new GridBagLayout());
    jTextAreaNames = new JTextArea[numPlayers+1];

    for (int y = 1; y <= numPlayers; y++) {

        createHeader();

        jTextAreaNames[y] = new JTextArea(2, 8);
        jTextAreaNames[y].setEditable(true);
        addDocumentListener(jTextAreaNames[y]);

        add(jTextAreaNames[y], GridBag.constraints(0, y, 1, 1));

        for (int i = 1; i <= 9; i++) {
            add(new BowlingFramePanel(2), GridBag.constraints(i, y, 1, 1));
        }
        add(new BowlingFramePanel(3), GridBag.constraints(10, y, 1, 1));

        jTextAreaTotalSum = new JTextArea(2, 8);
        jTextAreaTotalSum.setEditable(false);

        add(jTextAreaTotalSum, GridBag.constraints(11, y, 1, 1));
    }

}

Then the validateInputName method with a little change

private void validateInputName() {

    for (JTextArea jTextArea : jTextAreaNames) {

        if(jTextArea == null) continue;

        String text = jTextArea.getText();
        Pattern r = Pattern.compile(pattern);
        Matcher m = r.matcher(text);

        if (m.matches()) {
            jTextArea.setBackground(Color.GREEN);
            ifTextAreaIsEmptySetBackgroundColorWhite(jTextArea, text);
        } else {
            jTextArea.setBackground(Color.RED);
            ifTextAreaIsEmptySetBackgroundColorWhite(jTextArea, text);
        }
    }
}

I think no need to use a list class object. you don't forget check the null value of the array objects because the first jtextfield is always null.

if(jTextArea == null) continue;

Here is my full code with some imagination.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class GridPanel extends JPanel {

    private String[] COLUMNS = { "Name", "Frame 1", "Frame 2", "Frame 3", "Frame 4", "Frame 5", "Frame 6", "Frame 7",
            "Frame 8", "Frame 9", "Frame 10", "Total Sum" };

    private JTextArea[] jTextAreaNames;
    public JTextArea jTextAreaTotalSum;
    private JLabel labelName;
    private JLabel labelFrame;
    private JLabel labelSum;
    private static String pattern = "[A-Za-z]*";
    //public static List<JTextArea> jTextAreas = new ArrayList<>();


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

            public void run() {
                int numPlayers = 10;
                JFrame frame = new JFrame();
                frame.add(new GridPanel(numPlayers));
                frame.setPreferredSize(new Dimension(800,600));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                //frame.getContentPane().add(mainPanel);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }


    public GridPanel(int numPlayers) {
        setLayout(new BorderLayout());
        createGrid(numPlayers);
    }

    static class GridBag
    {
        static GridBagConstraints constraints(int gx, int gy, int gw, int gh)
        {
            GridBagConstraints c = new GridBagConstraints();
            c.gridx = gx;
            c.gridy = gy;
            c.gridheight = gh;
            c.gridwidth = gw;

            return c;
        }
    }

    class BowlingFramePanel extends JPanel
    {
        BowlingFramePanel(int a)
        {

        }
    }

    public void createGrid(int numPlayers) {

        setLayout(new GridBagLayout());
        jTextAreaNames = new JTextArea[numPlayers+1];

        for (int y = 1; y <= numPlayers; y++) {

            createHeader();

            jTextAreaNames[y] = new JTextArea(2, 8);
            jTextAreaNames[y].setEditable(true);
            addDocumentListener(jTextAreaNames[y]);

            add(jTextAreaNames[y], GridBag.constraints(0, y, 1, 1));

            for (int i = 1; i <= 9; i++) {
                add(new BowlingFramePanel(2), GridBag.constraints(i, y, 1, 1));
            }
            add(new BowlingFramePanel(3), GridBag.constraints(10, y, 1, 1));

            jTextAreaTotalSum = new JTextArea(2, 8);
            jTextAreaTotalSum.setEditable(false);

            add(jTextAreaTotalSum, GridBag.constraints(11, y, 1, 1));
        }

    }

    private void addDocumentListener(JTextArea jTextArea) {
        jTextArea.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                validateInputName();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                validateInputName();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                validateInputName();
            }
        });
    }

    private void validateInputName() {

        //jTextAreas.add(jTextAreaName);

        for (JTextArea jTextArea : jTextAreaNames) {

            if(jTextArea == null) continue;

            String text = jTextArea.getText();
            Pattern r = Pattern.compile(pattern);
            Matcher m = r.matcher(text);

            if (m.matches()) {
                jTextArea.setBackground(Color.GREEN);
                ifTextAreaIsEmptySetBackgroundColorWhite(jTextArea, text);
            } else {
                jTextArea.setBackground(Color.RED);
                ifTextAreaIsEmptySetBackgroundColorWhite(jTextArea, text);
            }
        }
    }

    private void ifTextAreaIsEmptySetBackgroundColorWhite(JTextArea jTextArea, String text) {
        if (text.isEmpty()) {
            jTextArea.setBackground(Color.WHITE);
        }
    }

    private void createHeader() {
        labelName = new JLabel(COLUMNS[0]);
        labelName.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));

        add(labelName, GridBag.constraints(0, 0, 1, 1));

        for (int x = 1; x <= 10; x++) {

            labelFrame = new JLabel(" " + "Frame " + Integer.toString(x));
            labelFrame.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));

            add(labelFrame, GridBag.constraints(x, 0, 1, 1));
        }

        labelSum = new JLabel(" " + COLUMNS[11]);
        labelSum.setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
        add(labelSum, GridBag.constraints(11, 0, 1, 1));

    }
}