Home > Software engineering >  How to access the objects of the array of JTextField objects in the KeyListener?
How to access the objects of the array of JTextField objects in the KeyListener?

Time:03-25

I have this code, that use an array of the JTextField objects for 25 elements and I want that ever element will be handle by KeyListener (keyPressed) differently after changing or adding text there.

So how can I get an index of the changed field into the listener?

For exist, 10-th element will change the background of the field to the green after adding or changing there text by user.

    public JTextField field[];
public void TextFilling(){
    field = new JTextField[25]; Font font = new Font("Times new Roman", Font.BOLD ,30);
    textChangedListener listener = new textChangedListener();

    //There are the process of formating size, location and other settings of the elements:
    for (int i = 0, j=0, k=0; i< field.length; i  , k  ) {field[i] = new JTextField();
        if (k==j) field[i].setText("1");
        if (i % 5 == 0 && i!=0) {j  ; k = 0;}
        field[i].setBounds(5 (100*(k 1)), 5 (100*(j 1)), 95, 95);
        field[i].setHorizontalAlignment(JTextField.CENTER); field[i].setFont(font);

        frame.add(field[i]);
        field[i].addKeyListener(listener);
    }
}
class textChangedListener implements KeyListener
{
    public void keyPressed(KeyEvent e){
        
    }
    public void keyReleased(KeyEvent e){}

    public void keyTyped(KeyEvent e){}
}

CodePudding user response:

Don't use KeyListener on text components, it's not helpful and you might end up in the middle of mutation of the state.

Instead, use a DocumentListener to monitor the changes to the text field, see How to Write a Document Listener for more details.

You should also be making use of dependency injection, basically passing information to the classes which need to interact with your program.

See:

for more information.

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private List<JTextField> textFields;

        public TestPane() {
            setBorder(new EmptyBorder(64, 64, 64, 64));
            setLayout(new GridBagLayout());

            Font font = new Font("Times new Roman", Font.BOLD, 30);
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.ipadx = 75;
            gbc.ipady = 75;
            gbc.insets = new Insets(8, 8, 8, 8);
            for (int row = 0; row < 5; row  ) {
                for (int col = 0; col < 5; col  ) {
                    gbc.gridx = col;
                    gbc.gridy = row;
                    JTextField field = new JTextField(1);
                    field.setHorizontalAlignment(JTextField.CENTER);
                    field.setFont(font);
                    textFields.add(field);

                    if (row == col) {
                        field.setText("1");
                    }

                    int index = ((row * 5)   col)   1;
                    if (index % 10 == 0) {
                        field.getDocument().addDocumentListener(new DocumentHighlighter(field));
                    }
                    add(field, gbc);
                }
            }
        }

        public class DocumentHighlighter implements DocumentListener {

            private JTextField field;
            private Color defaultColor;

            public DocumentHighlighter(JTextField field) {
                this.field = field;
                defaultColor = field.getBackground();
            }

            protected void highlightFieldIfRequired() {
                if (field.getText().isEmpty()) {
                    field.setBackground(defaultColor);
                } else {
                    field.setBackground(Color.GREEN);
                }
            }

            @Override
            public void insertUpdate(DocumentEvent e) {
                highlightFieldIfRequired();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                highlightFieldIfRequired();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                highlightFieldIfRequired();
            }            
        }
    }
}

One of the things I can see which is about to step up smack you then face, is how you share and manage data.

One concept you want to spend some time looking into, is the way you decouple your responsibilities. One of the ways this can be done is via a "model". A model is responsible for managing the state and rules associated with the data. The view then becomes responsible for presenting the current state of the model and updating the model based on the user input.

See:

One of the key elements to this concept is the use of the observer pattern. You've already seen this at work, as Swing listeners are observers.

Oh, and you really, really want to take the time and learn and understand the layout manager API. See Laying Out Components Within a Container for more details

  • Related