How to get the value of a Jspinner inside a loop?

Asked

Viewed 497 times

0

I am mounting a screen where products are displayed from a database: product title, price, button and a spinner. I try to give a jspinner getValue, but it does not return the value that the user indicates.

public class Minimo extends JFrame {

    JSpinner spinner = new JSpinner();
    JButton botao = new JButton("adicionar");

    JScrollPane scrollPane = new JScrollPane();
    JPanel panel = new JPanel(new GridLayout(0, 2));

    public Minimo() throws HeadlessException {
        super("Produtos em Estoque");

        for (int i = 0; i < 10; i++) {
            spinner = new JSpinner();
            botao = new JButton();
            botao.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent arg0) {
                    System.out.println(spinner.getValue());

                }
            });

            panel.add(botao);
            panel.add(spinner);

        }

        add(panel);
        setVisible(true);
        setSize(1360, 720);


    }




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

When I click on the corresponding jspinner button, the value contained in jspinner is not displayed on the console.

print da tela

1 answer

3


This code will not work as you expect because with each loop iteration, you create a spinner and a related button, but in the next iteration, you lose any reference to those that were created in the previous iteration.

The fact of using variables with very wide scope within the loop only makes the situation worse, because only the button and spinner of the last iteration will be stored. For this reason, all buttons reflect only what is marked on the last spinner.

The simplest solution would be to store the spinners and buttons in arrays, and to use their Internet to identify them in the Reader. Remembering that, as it has the same number of buttons and spinners, I used the boot index to identify the related spinner:

import java.awt.GridLayout;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.SwingUtilities;
import javax.swing.JOptionPane;

public class Minimo extends JFrame {

    JSpinner[] spinners = new JSpinner[10];
    JButton[] botoes = new JButton[10];

    JScrollPane scrollPane = new JScrollPane();
    JPanel panel = new JPanel(new GridLayout(0, 2));

    public Minimo()  {
        super("Produtos em Estoque");

        for (int i = 0; i < 10; i++) {

            JSpinner spinner = new JSpinner();
            JButton botao = new JButton();
            botao.setActionCommand(String.valueOf(i));

            botao.addActionListener(e -> {

                    JButton btn =  (JButton) e.getSource();
                    int index = Integer.valueOf(btn.getActionCommand());
                    JOptionPane.showMessageDialog(null, "Valor do spinner " + (index+1) + ": " + spinners[index].getValue());
            });

            spinners[i] = spinner;
            botoes[i] = botao;

            panel.add(botao);
            panel.add(spinner);

        }

        add(panel);
        setVisible(true);
        setSize(1360, 720);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args) {

            SwingUtilities.invokeLater(Minimo::new);
    }
}

In the code above, I also used setActionCommand() on the buttons, because you need to pass a fixed reference from the Indice to the System, otherwise the same problem of always picking the last one will occur. With this command, I record the Dice on each button, so when you pass the Switch, it will take the correct Dice from the spinner that that button is relative to.

Another error in your code is not defining the behavior of the window when it is closed. By default, the window is only hidden, running in the background, you need to change this behavior otherwise the user of your application will not be able to open the window a second time, unless you restart the computer. So I added the line setDefaultCloseOperation(EXIT_ON_CLOSE); in the code, it causes the window to be actually closed, terminating the application correctly.

Finally, you are not dispatching your application to the recommend you read Why the main method should dispatch the creation of the GUI to the EDT in a swing application? and fix your code.

See in operation the corrected code:

inserir a descrição da imagem aqui

  • Thank you very much for the reply Articuno, and also for the tip.

  • @teophilo made some changes, I recommend you take a read again when you can.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.