从一个内部类引用 [英] Referencing from an inner class

查看:172
本文介绍了从一个内部类引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code

 进口的javax.swing *。
进口java.awt中的*。
进口net.miginfocom.swing.MigLayout;
进口排序*。
javax.swing.event中导入*。
java.awt.event中导入*。
进口java.awt.Color中;公共类SortsGui
{
    JFrame的myMainWindow =新的JFrame(排序);    JPanel的sortPanel =新JPanel();    //第一面板组件
    公众诠释nextTextBox = 20;
    JTextField的[] allField =新的JTextField,[25];
    //结束第一盘    公共无效runGUI()
    {
        myMainWindow.setBounds(10,10,800,800);
        myMainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        myMainWindow.setLayout(新的GridLayout(1,1));        createSortTestPanel();        myMainWindow.getContentPane()加(sortPanel)。        myMainWindow.setVisible(真);
    }    公共无效createSortTestPanel()
    {
        MigLayout布局=新MigLayout(,[成长]);
        sortPanel.setLayout(布局);        refreshScreen();
    }    公共无效refreshScreen()
    {
        sortPanel.removeAll();        的for(int i = 0; I< nextTextBox;我++)
        {
            INT修复= I + 1;
            allField [I] =新的JTextField();
            sortPanel.add(allField [I]中,growx);
            allField [I] .addKeyListener(新的KeyListener()
            {
                公共无效键pressed(KeyEvent e而)
                {                }                公共无效调用keyReleased(KeyEvent e而)
                {                }                公共无效的keyTyped(KeyEvent e而)
                {
                    焦C = e.getKeyChar();
                    如果(Character.isDigit(c))的
                    {                    }                    其他
                    {
                        e.consume();
                    }                    尝试
                    {
                        INT parseTest =的Integer.parseInt(allField [I] .getText());
                    }                    赶上(例外EXC)
                    {
                        allField [I] .setBackground(Color.RED);
                    }
                }
            });
        }
    }    公共静态无效的主要(字串[] args)
    {
        SortsGui SG =新SortsGui();
        sG.runGUI();
    }
}

在这里,我的目标是创建JTextField的数组,它有一个的KeyListener。这应的KeyListener比$在JTextField中所输入的数字另一个p $ pvent什么。它也应该改变JTextField的背景颜色,如果输入的数字不是一个int。例如2147483647554。
然而,当我编译这个我得到的错误

那么,如何使这使得它要么是最终还是在所有JTextField的有效决赛?


解决方案

  

在这里,我的目标是创建JTextField的数组,它有一个的KeyListener。这应该KeyListener的$数字之外的其他JTextField中被输入p $ pvent什么


简短的回答因而,不要使用的KeyListener ,也不会在用户粘贴文本的用例捕捉到现场或者如果该字段是编程更新

相反,你需要使用的DocumentFilter ,例如:

 公共类IntFilter扩展的DocumentFilter {    @覆盖
    公共无效insertString(DocumentFilter.FilterBypass FB,诠释抵消,字符串文字的AttributeSet attr)使用抛出BadLocationException的{        StringBuilder的缓冲=新的StringBuilder(text.length());
        对于(INT指数= 0;指数 - LT; text.length();指数++){
            如果(Character.isDigit(text.charAt(索引))){
                buffer.append(text.charAt(指数));
            }
        }
        super.insertString(FB,偏移,buffer.toString(),attr)使用;
        ValidationListener听者= getValidationListener();
    }    @覆盖
    公共无效替换(DocumentFilter.FilterBypass FB,诠释抵消,诠释长度,串串,AttributeSet中的attr)使用抛出BadLocationException的{
        如果(长度大于0){
            fb.remove(偏移,长度);
        }
        insertString(FB,偏移,字符串attr)使用;
    }
}

请参阅有关详细信息,实现文档过滤器的DocumentFilter例子获取更多的例子。


  

这也应该改变JTextField的背景颜色,如果输入的数字不是int


您可以使用 InputVerifier ,但可能无法满足您的需求做后期的验证。

这将创建一个问题。在的DocumentFilter ,不应该关心它的应用领域,但因为它做验证,它会知道什么时候出了问题,所以我们需要某种方式过滤器验证失败提供通知...

首先,我们需要一些回调它告诉我们在验证失败或通过...

 公共接口ValidationListener {    公共无效validationFailed();    公共无效validationPassed();
}

然后我们需要在此基础上的规则更新过滤器,以提高这些通知...

 公共类IntFilter扩展的DocumentFilter {    私人ValidationListener validationListener;    公共无效setValidationListener(ValidationListener validationListener){
        this.validationListener = validationListener;
    }    公共ValidationListener getValidationListener(){
        返回validationListener;
    }    @覆盖
    公共无效insertString(DocumentFilter.FilterBypass FB,诠释抵消,字符串文字的AttributeSet attr)使用抛出BadLocationException的{        布尔validationFailed = FALSE;
        StringBuilder的缓冲=新的StringBuilder(text.length());
        对于(INT指数= 0;指数 - LT; text.length();指数++){
            如果(Character.isDigit(text.charAt(索引))){
                buffer.append(text.charAt(指数));
            }其他{
                validationFailed = TRUE;
            }
        }
        super.insertString(FB,偏移,buffer.toString(),attr)使用;
        ValidationListener听者= getValidationListener();
        如果(听众!= NULL){
            如果(validationFailed){
                listener.validationFailed();
            }其他{
                listener.validationPassed();
            }
        }
    }    @覆盖
    公共无效替换(DocumentFilter.FilterBypass FB,诠释抵消,诠释长度,串串,AttributeSet中的attr)使用抛出BadLocationException的{
        如果(长度大于0){
            fb.remove(偏移,长度);
        }
        insertString(FB,偏移,字符串attr)使用;
    }
}

然后,我们需要确定我们的实施 ValidationListener 来执行我们所需要的行动......

 公共类DefaultValidationHandler实现ValidationListener {    私人的JTextField场;    公共DefaultValidationHandler(JTextField的领域){
        this.field =领域;
    }    公共JTextField的getfield命令(){
        回场;
    }    @覆盖
    公共无效validationFailed(){
        。getfield命令()的setBackground(Color.RED);
    }    @覆盖
    公共无效validationPassed(){
        getfield命令()的setBackground(UIManager.getColor(TextField.background))。
    }}

下面,听者保持,这是我们要控制字段的引用

然后,我们干脆把它绑定...

  JTextField的领域=新的JTextField(10);
DefaultValidationHandler处理程序=新DefaultValidationHandler(场);
IntFilter过滤器=新IntFilter();
filter.setValidationListener(处理);
((是AbstractDocument)field.getDocument())setDocumentFilter(过滤器)。

这是所有有点粗糙,但它横跨得到的基本思想。

一些改进可能包括合格的参考的DocumentFilter 通过的 ValidationListener ,然后你可以在方法回用它来查找这些触发事件的现场和更新,降低了处理器的数量,您可能需要创建,例如。

例如

更新ValidationListener

 公共接口ValidationListener {    公共无效validationFailed(的DocumentFilter过滤器);    公共无效validationPassed(的DocumentFilter过滤器);
}

更新IntFilter

 公共类IntFilter扩展的DocumentFilter {    私人ValidationListener validationListener;    公共无效setValidationListener(ValidationListener validationListener){
        this.validationListener = validationListener;
    }    公共ValidationListener getValidationListener(){
        返回validationListener;
    }    @覆盖
    公共无效insertString(DocumentFilter.FilterBypass FB,诠释抵消,字符串文字的AttributeSet attr)使用抛出BadLocationException的{        布尔validationFailed = FALSE;
        StringBuilder的缓冲=新的StringBuilder(text.length());
        对于(INT指数= 0;指数 - LT; text.length();指数++){
            如果(Character.isDigit(text.charAt(索引))){
                buffer.append(text.charAt(指数));
            }其他{
                validationFailed = TRUE;
            }
        }
        super.insertString(FB,偏移,buffer.toString(),attr)使用;
        ValidationListener听者= getValidationListener();
        如果(听众!= NULL){
            如果(validationFailed){
                listener.validationFailed(本);
            }其他{
                listener.validationPassed(本);
            }
        }
    }    @覆盖
    公共无效替换(DocumentFilter.FilterBypass FB,诠释抵消,诠释长度,串串,AttributeSet中的attr)使用抛出BadLocationException的{
        如果(长度大于0){
            fb.remove(偏移,长度);
        }
        insertString(FB,偏移,字符串attr)使用;
    }
}

例实施...

 公共类TestPane继承JPanel {    私人地图<的DocumentFilter,JTextField的>领域;    公共TestPane(){        域=新的HashMap<>(25);
        ValidationListener监听器=新ValidationListener(){            @覆盖
            公共无效validationFailed(的DocumentFilter过滤器){
                JTextField的领域= fields.get(过滤器);
                如果(场!= NULL){
                    field.setBackground(Color.RED);
                }
            }            @覆盖
            公共无效validationPassed(的DocumentFilter过滤器){
                JTextField的领域= fields.get(过滤器);
                如果(场!= NULL){
                    field.setBackground(UIManager.getColor(TextField.background));
                }
            }
        };        的setLayout(新的GridBagLayout());
        GridBagConstraints的GBC =新的GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        对于(INT指数= 0;指数小于10,指数++){
            JTextField的领域=新的JTextField(10);
            IntFilter过滤器=新IntFilter();
            filter.setValidationListener(监听);
            ((是AbstractDocument)field.getDocument())setDocumentFilter(过滤器)。
            fields.put(过滤器,场);
            增加(场,GBC);
        }    }}

I have the following code

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();
    }
}

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. It should also change the color of the JTextField's background if the number entered is not an int. For example 2147483647554. However when I compile this I get the error

So how do I make this so that it is either final or effectively final on all the JTextFields?

解决方案

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

The short answer to thus is, don't use KeyListener, it won't capture the use cases of the user pasting text into the field or if the field is updated programmatically

Instead you want to use a DocumentFilter, for example

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);
    }
}

See Implementing a Document Filter for more details and DocumentFilter Examples for more examples

It should also change the color of the JTextField's background if the number entered is not an int

You can do post validation using a InputVerifier, but that might not meet your needs.

This creates a problem. The DocumentFilter, shouldn't care about the field it's applied to, but since, it's doing the validation, it will know when something has gone wrong, so we need some way for the filter to provide notification when the validation fails...

First, we need some callback which tells us when validation has failed or passed...

public interface ValidationListener {

    public void validationFailed();

    public void validationPassed();
}

Then we need to update the filter to raise those notifications based on it's rules...

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);
    }
}

Then we need to define our implementation of the ValidationListener to perform the actions we need...

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"));
    }

}

Here, the listener maintains a reference to the field which we want to control

Then we bind it altogether...

JTextField field = new JTextField(10);
DefaultValidationHandler handler = new DefaultValidationHandler(field);
IntFilter filter = new IntFilter();
filter.setValidationListener(handler);
((AbstractDocument)field.getDocument()).setDocumentFilter(filter);

This is all a bit crude, but it gets the basic idea across.

Some improvements might include passing the reference of the DocumentFilter back via the methods of the ValidationListener, you could then use this to lookup the field which triggered the event and update it, reducing the number of handlers you might need to create, for example.

For example

Updated ValidationListener

public interface ValidationListener {

    public void validationFailed(DocumentFilter filter);

    public void validationPassed(DocumentFilter filter);
}

Updated 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);
    }
}

Example implementation...

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);
        }

    }

}

这篇关于从一个内部类引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆