从内部引用 class
Referencing from an inner class
我有以下代码
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();
}
}
我的目标是创建一个 JTextFields 数组,其中有一个 keylistener。此键侦听器应防止在 JTextField 中输入数字以外的任何内容。如果输入的数字不是 int,它还应该更改 JTextField 背景的颜色。例如 2147483647554。
但是当我编译这个时我得到错误
那么我该如何做到这一点,以便它在所有 JTextFields 上都是最终的或有效的最终的?
您遇到了范围界定问题,这就是出现此错误的原因:
for(int i = 0; i<nextTextBox;i++) //you are declaring i here
在KeyListener
里面使用,这是被禁止的。因为无法从内部 class 访问 local
non-final
变量来访问它必须是最终的。在你的情况下,我认为不可能使 i
成为最终的
因此,一个快速解决方法是在 class 范围内使用 JFrame
和 JPanel
声明 i
JFrame myMainWindow = new JFrame("Sorts");
JPanel sortPanel = new JPanel();
int i;
然后在任何地方使用它
for(i = 0; i<nextTextBox;i++)
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 for more details and DocumentFilter Examples
It should also change the color of the JTextField's background if the number entered is not an int
您可以使用 InputVerifier
进行 post 验证,但这可能无法满足您的需求。
这会产生一个问题。 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"));
}
}
在这里,侦听器维护对我们要控制的字段的引用
然后我们一起绑定...
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);
}
}
}
我有以下代码
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();
}
}
我的目标是创建一个 JTextFields 数组,其中有一个 keylistener。此键侦听器应防止在 JTextField 中输入数字以外的任何内容。如果输入的数字不是 int,它还应该更改 JTextField 背景的颜色。例如 2147483647554。 但是当我编译这个时我得到错误
那么我该如何做到这一点,以便它在所有 JTextFields 上都是最终的或有效的最终的?
您遇到了范围界定问题,这就是出现此错误的原因:
for(int i = 0; i<nextTextBox;i++) //you are declaring i here
在KeyListener
里面使用,这是被禁止的。因为无法从内部 class 访问 local
non-final
变量来访问它必须是最终的。在你的情况下,我认为不可能使 i
成为最终的
因此,一个快速解决方法是在 class 范围内使用 JFrame
和 JPanel
JFrame myMainWindow = new JFrame("Sorts");
JPanel sortPanel = new JPanel();
int i;
然后在任何地方使用它
for(i = 0; i<nextTextBox;i++)
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 for more details and DocumentFilter Examples
It should also change the color of the JTextField's background if the number entered is not an int
您可以使用 InputVerifier
进行 post 验证,但这可能无法满足您的需求。
这会产生一个问题。 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"));
}
}
在这里,侦听器维护对我们要控制的字段的引用
然后我们一起绑定...
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);
}
}
}