我有以下代码
import javax.swing.*;
import java.awt.*;
import net.miginfocom.swing.MigLayout;
import Sorts.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.Color;
public class SortsGui
{
JFrame myMainWindow = new JFrame("Sorts");
JPanel sortPanel = new JPanel();
//first panel components
public int nextTextBox = 20;
JTextField[] allField = new JTextField [25];
//end first panel
public void runGUI()
{
myMainWindow.setBounds(10, 10, 800, 800);
myMainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myMainWindow.setLayout(new GridLayout(1,1));
createSortTestPanel();
myMainWindow.getContentPane().add(sortPanel);
myMainWindow.setVisible(true);
}
public void createSortTestPanel()
{
MigLayout layout = new MigLayout("" , "[grow]");
sortPanel.setLayout(layout);
refreshScreen();
}
public void refreshScreen()
{
sortPanel.removeAll();
for(int i = 0; i<nextTextBox;i++)
{
int fix = i+1;
allField[i] = new JTextField("");
sortPanel.add(allField[i],"growx");
allField[i].addKeyListener(new KeyListener ()
{
public void keyPressed(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
}
public void keyTyped(KeyEvent e)
{
char c = e.getKeyChar();
if(Character.isDigit(c))
{
}
else
{
e.consume();
}
try
{
int parseTest = Integer.parseInt(allField[i].getText());
}
catch(Exception exc)
{
allField[i].setBackground(Color.RED);
}
}
});
}
}
public static void main(String[] args)
{
SortsGui sG = new SortsGui();
sG.runGUI();
}
}
我的目标是创建一个具有按键监听器的 JTextField 数组。此键监听器应阻止在 JTextField 中输入除数字之外的任何内容。如果输入的数字不是 int,它还应该更改 JTextField 背景的颜色。例如 2147483647554。 但是,当我编译这个时,我收到错误
那么我该如何使其成为所有 JTextField 上的最终或有效最终?
最佳答案
My aim here is to create an array of JTextFields which have a keylistener on. This keylistener should prevent anything other than numbers being entered in the JTextField
对此问题的简短回答是,不要使用KeyListener
,它不会捕获用户将文本粘贴到字段中或以编程方式更新字段的用例
例如,您想使用DocumentFilter
public class IntFilter extends DocumentFilter {
@Override
public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
StringBuilder buffer = new StringBuilder(text.length());
for (int index = 0; index < text.length(); index++) {
if (Character.isDigit(text.charAt(index))) {
buffer.append(text.charAt(index));
}
}
super.insertString(fb, offset, buffer.toString(), attr);
ValidationListener listener = getValidationListener();
}
@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException {
if (length > 0) {
fb.remove(offset, length);
}
insertString(fb, offset, string, attr);
}
}
参见Implementing a Document Filter了解更多详情和 DocumentFilter Examples更多示例
It should also change the color of the JTextField's background if the number entered is not an int
您可以使用 InputVerifier
进行后验证,但这可能无法满足您的需求。
这会产生一个问题。 DocumentFilter
不应该关心它所应用的字段,但是由于它正在执行验证,因此它会知道何时出现问题,因此我们需要某种方式让过滤器在出现问题时提供通知验证失败...
首先,我们需要一些回调来告诉我们验证何时失败或通过......
public interface ValidationListener {
public void validationFailed();
public void validationPassed();
}
然后我们需要更新过滤器以根据其规则发出这些通知...
public class IntFilter extends DocumentFilter {
private ValidationListener validationListener;
public void setValidationListener(ValidationListener validationListener) {
this.validationListener = validationListener;
}
public ValidationListener getValidationListener() {
return validationListener;
}
@Override
public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
boolean validationFailed = false;
StringBuilder buffer = new StringBuilder(text.length());
for (int index = 0; index < text.length(); index++) {
if (Character.isDigit(text.charAt(index))) {
buffer.append(text.charAt(index));
} else {
validationFailed = true;
}
}
super.insertString(fb, offset, buffer.toString(), attr);
ValidationListener listener = getValidationListener();
if (listener != null) {
if (validationFailed) {
listener.validationFailed();
} else {
listener.validationPassed();
}
}
}
@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException {
if (length > 0) {
fb.remove(offset, length);
}
insertString(fb, offset, string, attr);
}
}
然后我们需要定义 ValidationListener
的实现来执行我们需要的操作...
public class DefaultValidationHandler implements ValidationListener {
private JTextField field;
public DefaultValidationHandler(JTextField field) {
this.field = field;
}
public JTextField getField() {
return field;
}
@Override
public void validationFailed() {
getField().setBackground(Color.RED);
}
@Override
public void validationPassed() {
getField().setBackground(UIManager.getColor("TextField.background"));
}
}
这里,监听器维护了对我们想要控制的字段的引用
然后我们将其完全绑定(bind)...
JTextField field = new JTextField(10);
DefaultValidationHandler handler = new DefaultValidationHandler(field);
IntFilter filter = new IntFilter();
filter.setValidationListener(handler);
((AbstractDocument)field.getDocument()).setDocumentFilter(filter);
这有点粗糙,但它传达了基本思想。
一些改进可能包括通过 ValidationListener
的方法传回 DocumentFilter
的引用,然后您可以使用它来查找触发事件并更新的字段例如,减少您可能需要创建的处理程序的数量。
例如
更新了 ValidationListener
public interface ValidationListener {
public void validationFailed(DocumentFilter filter);
public void validationPassed(DocumentFilter filter);
}
更新了 IntFilter
public class IntFilter extends DocumentFilter {
private ValidationListener validationListener;
public void setValidationListener(ValidationListener validationListener) {
this.validationListener = validationListener;
}
public ValidationListener getValidationListener() {
return validationListener;
}
@Override
public void insertString(DocumentFilter.FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
boolean validationFailed = false;
StringBuilder buffer = new StringBuilder(text.length());
for (int index = 0; index < text.length(); index++) {
if (Character.isDigit(text.charAt(index))) {
buffer.append(text.charAt(index));
} else {
validationFailed = true;
}
}
super.insertString(fb, offset, buffer.toString(), attr);
ValidationListener listener = getValidationListener();
if (listener != null) {
if (validationFailed) {
listener.validationFailed(this);
} else {
listener.validationPassed(this);
}
}
}
@Override
public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String string, AttributeSet attr) throws BadLocationException {
if (length > 0) {
fb.remove(offset, length);
}
insertString(fb, offset, string, attr);
}
}
示例实现...
public class TestPane extends JPanel {
private Map<DocumentFilter, JTextField> fields;
public TestPane() {
fields = new HashMap<>(25);
ValidationListener listener = new ValidationListener() {
@Override
public void validationFailed(DocumentFilter filter) {
JTextField field = fields.get(filter);
if (field != null) {
field.setBackground(Color.RED);
}
}
@Override
public void validationPassed(DocumentFilter filter) {
JTextField field = fields.get(filter);
if (field != null) {
field.setBackground(UIManager.getColor("TextField.background"));
}
}
};
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
for (int index = 0; index < 10; index++) {
JTextField field = new JTextField(10);
IntFilter filter = new IntFilter();
filter.setValidationListener(listener);
((AbstractDocument) field.getDocument()).setDocumentFilter(filter);
fields.put(filter, field);
add(field, gbc);
}
}
}
关于java - 从内部类引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30908040/