Home > Back-end >  How to create an array with random numbers and send it to listener without randomizing it again?
How to create an array with random numbers and send it to listener without randomizing it again?

Time:02-11

So i'm trying to create a program that create an array of 100 random numbers (without changing everytime user reacts to it), and allow users to check the numbers by entering the index of it. However, the array keep randomizing everytime the user pressed the Show Element button.

I also tried to create the array on the main program, but I then faced the error because the listener can't access the array. Please enlighten me as I'm new to this Java GUI Programming. Any help is much appreciated.

import java.util.Random;
import javax.swing.*;
import java.awt.GridLayout;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.*;

public class P3Q2 extends JFrame {

    private JTextField text1 = new JTextField(10);
    private JTextField text2 = new JTextField(10);
    private int arr[];

    private JButton jbtShow = new JButton("Show Element");

    public P3Q2() {
        JPanel jpTextField = new JPanel();
        jpTextField.setLayout(new GridLayout(3, 2));
        jpTextField.add(new JLabel("Array Index"));
        jpTextField.add(text1);
        jpTextField.add(new JLabel("Array Element"));
        jpTextField.add(text2);
        text2.setEditable(false);

        JPanel jpButtons = new JPanel();
        jpButtons.add(jbtShow);

        add(jpTextField);
        add(jpButtons, BorderLayout.SOUTH);

        jbtShow.addActionListener(new ButtonListener());

        setTitle("Display: Show Bounds Error");
        setSize(400, 150);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    private class ButtonListener implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            try {
                Random rd = new Random(); // creating Random object
                int[] arr = new int[100];
                for (int i = 0; i < arr.length; i  ) {
                    arr[i] = rd.nextInt(); // storing random integers in an array
                }

                if (e.getSource() == jbtShow) {
                    int num = Integer.parseInt(text1.getText());
                    int result = arr[num];
                    text2.setText(""   result);
                }
            } catch (ArrayIndexOutOfBoundsException ex) {
                text2.setText("Out of bound!");
            }

        }
    }

    public static void main(String[] args) {
        P3Q2 test = new P3Q2();
    }
}

CodePudding user response:

In the constructor you are assigning the random numbers to a local variable arr that is overriding the private attribute arr with the same name

Try changing it to:

Random rd = new Random(); // creating Random object
arr = new int[100];
for (int i = 0; i < arr.length; i  ) {
    arr[i] = rd.nextInt(); // storing random integers in an array
}

CodePudding user response:

Although you are shadowing your arr field you are still creating a new array each time an event is processed which is something you said you didn't want to do.

Doing significant processing in the Event Dispatch Thread is not a good idea. It can tie up the GUI. Even though you're only generating 100 random numbers I recommend initializing the array and then just reusing it.

You can do that by having an initialization block in your ButtonListener class. Then subsequent events will simply use that array without recreating it. The array will be created upon instantiation of your ButtonListener.

private class ButtonListener implements ActionListener {
    private int arr[] = new int[100];
    {
        Random rd = new Random();
        for (int i = 0; i < arr.length; i  ) {
            arr[i] = rd.nextInt(); // storing random integers in an array
            
        }
    }
    
    public void actionPerformed(ActionEvent e) {
        try {
            if (e.getSource() == jbtShow) {
                int num = Integer.parseInt(text1.getText());
                int result = arr[num];
                text2.setText(""   result);
            }
        } catch (ArrayIndexOutOfBoundsException ex) {
            text2.setText("Out of bound!");
        }
    }
}

If you need to access arr outside of the listener you can use your existing array declaration of private int[] arr; and simply use that in the ButtonListener class.

Another observation. Catching an exception would be a good idea for parseInt since the value might not be a number. But if the parsing is acceptable, why not just check to ensure it is between 0 and arr.length-1 inclusive?

  • Related