简体   繁体   中英

How to use array index without “Local variable x defined in an enclosing scope must be final…”

I'm writing a simple program, and there is one problem I cannot solve.

I am creating textFields with such loop:

 testText = new JTextField[9][9];
    for(int x = 0; x < 9; x++)
        for(int y = 0; y < 9; y++)
        {
            testText[x][y] = new JTextField();
            testText[x][y].setPreferredSize(new Dimension(30, 30));
            testText[x][y].setHorizontalAlignment(SwingConstants.CENTER);
            testText[x][y].setFont(new Font("Tahoma", Font.BOLD, 18));  
            testText[x][y].setBackground(Color.WHITE);
            testText[x][y].setEditable(false);
            testText[x][y].addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if( //blablabla )                       
                    testText[x][y].setText(value + "");
                }
            });
            panelMain.add(testText[x][y]);
        }

I want to use the x, and y to get the location of this "clicked" field, but the mysterious error apperas: "Local variable x defined in an enclosing scope must be final or effectively final" (same for "y")

In my project there would be checking function and it would be great if I could use those x and y as arguments like :

         checkIfPossibel(x,y,value); // "value" is global

Keep in mind that I am not a Java God and I would like to keep this work on understandable level(for me) if this is possible.

The best fix here is to simplify your code - remove all that duplication of testTest[x][y] by introducing a local variable which can be final (and thus allow you to use it within the anonymous inner class):

testText = new JTextField[9][9];
for (int x = 0; x < 9; x++) {
    for (int y = 0; y < 9; y++)
    {
        final JTextField field = new JTextField();
        testText[x][y] = field;
        field.setPreferredSize(new Dimension(30, 30));
        field.setHorizontalAlignment(SwingConstants.CENTER);
        field.setFont(new Font("Tahoma", Font.BOLD, 18));  
        field.setBackground(Color.WHITE);
        field.setEditable(false);
        field.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (//blablabla) {                       
                    field.setText(value + "");
                }
            }
        });
        panelMain.add(field);
    }
}

It's not clear whether you even need testText at this point, but I'll assume for the moment that you are referring to it somewhere else.

First, you need to understand why the compiler tells you that it cannot access non-final x and y . When you create new MouseAdapter() , variables x and y need to be "captured" for the constructor of the anonymous class. The value of non-final x and y is subject to change after the object has been created, which may lead to confusion, because the values of x and y that you observe inside and outside the mouseClicked method could be different. That is why Java language designers required that only final local variables could be used inside anonymous method implementations.

Now that you understand what is going on, coming up with the fix is simple: make final copies of x and y , and use them instead:

final int tmpX = x;
final int tmpY = x;
testText[x][y].addMouseListener(new MouseAdapter() {
    @Override
    public void mouseClicked(MouseEvent e) {
        if( //blablabla )                       
        testText[tmpX][tmpY].setText(value + "");
    }
});

Create a temporary final varable like this:

        testText[x][y].addMouseListener(new MouseAdapter() {
        final int x1 = x;
        final int y1 = y;
            @Override
            public void mouseClicked(MouseEvent e) {
                if( //blablabla )                       
                testText[x1][y1].setText(value + "");
            }
        });

Guys it was my first post here, and I'm stunned. You are ULTRA fast. BUT it does not work as it suppuose to.

To find out I've made something like that:

           final int tmpX = x;
            final int tmpY = x;
            Liczba[x][y].addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    pole =javax.swing.JTextField)e.getSource());
                    pole.setText(tmpX + " " + tmpY);                        

                }
            });

And it sets the number of row for example: for 0, its "0 0", for 6 "6 6" and so on.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM