JTextArea DocumentListener 问题
Posted
技术标签:
【中文标题】JTextArea DocumentListener 问题【英文标题】:JTextArea DocumentListener Issue 【发布时间】:2018-11-11 18:18:28 【问题描述】:Validation of jTextAreaName
以下代码使用 GridBagconstraints 创建一些 jTextAreaName。我的问题是我尝试使用 DocumentListener 验证 jTextAreaName 中的文本。但是它只验证最后一个 jTextAreaName。不是全部(见上图)。我认为这取决于 GridBagConstraints。但我不知道如何解决这个问题。
你有什么提示我应该改变什么吗?
提前致谢。
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));
【问题讨论】:
1) 为了尽快获得更好的帮助,请发帖 minimal reproducible example 或 Short, Self Contained, Correct Example。 2) 请参阅Detection/fix for the hanging close bracket of a code block 了解我无法再费心修复的问题。 3) “我认为这取决于 GridBagConstraints。” 我认为你错了,但证明在 MCVE / SSCCE 中,所以发布一个我们可以使用的! 【参考方案1】:我认为您应该在创建 JTexteAreas 后直接将它们添加到列表中。不在 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));
【讨论】:
【参考方案2】:您在 for 循环中使用了相同的对象。
for (int y = 1; y <= numPlayers; y++)
...
jTextAreaName = new JTextArea(2, 8);
jTextAreaName 仍然是相同的引用,因此只创建了最后一个 jtextarea。
你需要有足够的 JTextArea 对象,然后是 numPlayers 变量。
您的 createGrid 方法的一个可能选项如下
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));
然后把 validateInputName 方法稍微改动一下
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);
我认为没有必要使用列表类对象。 不要忘记检查数组对象的 null 值,因为第一个 jtextfield 始终为 null。
if(jTextArea == null) continue;
这是我的完整代码,带有一些想象力。
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));
【讨论】:
以上是关于JTextArea DocumentListener 问题的主要内容,如果未能解决你的问题,请参考以下文章