Dynamically update (refresh) a JDialog (swing)

1

I'm having some trouble updating JDialog created through WindowsBuilder in Eclipse (it would not be because of this).

Basically, I have a Change Registrations screen from my financial mini-system, I load the information on the logged in user's screen and display the others in a JComboBox .

I created a ActionListener so that when JComboBox is modified, it validates if the selected user is different from what is currently displayed. If it is, it loads the new information.

Below is a snippet of code trying to explain:

import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JPanel;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.util.ArrayList;

import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

import br.com.base_classes_paper.cadastroBase;
import br.com.classes_paper.cadastroActions;


public class altCadastroUsuario1 extends JDialog {

    private final JPanel contentPanel = new JPanel();
    private JTextField txtLogin;
    private JTextField passSenha;
    public cadastroBase valCadBas;
    public ArrayList<cadastroBase> cadTotal;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        try {
            altCadastroUsuario1 dialog = new altCadastroUsuario1();
            dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            dialog.setVisible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public altCadastroUsuario1() {

        setTitle("PaperSys");
        setBounds(100, 100, 800, 600);
        getContentPane().setLayout(new BorderLayout());
        contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        getContentPane().add(contentPanel, BorderLayout.CENTER);
        contentPanel.setLayout(null);

        txtLogin = new JTextField();
        txtLogin.setBounds(106, 165, 260, 20);
        txtLogin.setText(valCadBas.getLogin());
        contentPanel.add(txtLogin);
        txtLogin.setColumns(10);

        passSenha = new JTextField();
        passSenha.setBounds(468, 165, 270, 20);
        passSenha.setText(valCadBas.getPass());
        contentPanel.add(passSenha);
        passSenha.setColumns(10);

        JComboBox jComBox_NomeUsuar = new JComboBox();

        for (cadastroBase load : cadTotal){
            jComBox_NomeUsuar.addItem(load.login);
        }

        jComBox_NomeUsuar.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                String selected = (String) jComBox_NomeUsuar.getSelectedItem();
                if (selected.equalsIgnoreCase(txtLogin.getText())){
                    for (cadastroBase load : cadTotal){
                        if (selected.equalsIgnoreCase(load.nomes)){
                            valCadBas.setLogin(load.login);
                            valCadBas.setPass(load.pass);
                            recarregarTela();
                        }
                    }
                }

            }

        });
        jComBox_NomeUsuar.setBounds(539, 282, 199, 20);
        contentPanel.add(jComBox_NomeUsuar);

    }
    protected void recarregarTela() {
        //altCadastroUsuario.this.removeAll();
        altCadastroUsuario1.this.repaint();
        altCadastroUsuario1.this.revalidate();
        //contentPanel.repaint();
        //contentPanel.revalidate();
    }

}

In the case, my method would do more or less what is there, but with some extra fields and internal methods that run in other classes. But the way it is, it does not work.

To see if I can communicate better: I have the screen (generated by windows builder of eclipse) that initially displays the data of the user that was logged in the system (let's assume login and password) via get / set and the other information of all users of which it has access saved in an array loading only the logins in jcombobox, hence when it modifies some house in the combobox I validate if what it changes in the jcombobox is different from what it is showing on the screen, if yes I load the I am trying to get the refresh of the page through the methods revalidate() and repaint() whereby they do not update the register (the compiling java execute both but nothing happens next). If you need the whole code, I'll have it tomorrow because today I'm not home.

    
asked by anonymous 15.04.2015 / 03:44

1 answer

1

The best I got was that. I do not know what he should do exactly when reloading the screen, so I put a System.out.println there to demonstrate that the method was called. Whenever I select in JComboBox a name equal to JTextField , this function is called and the text is written in the console.

Here is the code:

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class AltCadastroUsuario extends JDialog {
    private final JPanel contentPanel;

    protected String nome;

    public static void main(String[] args) {
        EventQueue.invokeLater(AltCadastroUsuario::iniciar);
    }

    private static void iniciar() {
        try {
            AltCadastroUsuario dialog = new AltCadastroUsuario();
            dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            dialog.setSize(400, 200);
            dialog.setVisible(true);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public AltCadastroUsuario() {
        contentPanel = new JPanel();
        this.add(contentPanel);
        JTextField txtLogin = new JTextField();
        txtLogin.setText("Teste");
        contentPanel.add(txtLogin);

        JComboBox<String> jComBox_NomeUsuar = new JComboBox<>();
        jComBox_NomeUsuar.addItem("Pedro");
        jComBox_NomeUsuar.addItem("Carlos");
        contentPanel.add(jComBox_NomeUsuar);

        jComBox_NomeUsuar.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                String selected = (String) jComBox_NomeUsuar.getSelectedItem();
                if (selected.equalsIgnoreCase(txtLogin.getText())) {
                    nome = selected;
                    recarregarTela();
                }
            }
        });
    }

    protected void recarregarTela() {
        System.out.println("Recarregando");
        //altCadastroUsuario.this.removeAll();
        AltCadastroUsuario.this.repaint();
        AltCadastroUsuario.this.revalidate();
        //contentPanel.repaint();
        //contentPanel.revalidate();
    }
}

In your code there were the following problems:

  • You were using protect instead of protected , which caused a compile error ( as reviewed by Bruno César ).
  • Some casts were missing when using the getSelectedItem() method of JComboBox . This also caused a compilation error.
  • You did not give the whole class, which obviously makes your code non-compilable and leaves your question harder to answer. It took me some time to realize that altCadastroUsuario was the class name. However, I should not have to guess this by myself. In addition, class names should start with uppercase letters. I also had to deduce that altCadastroUsuario is subclass of JDialog .
  • Do not access Swing outside the AWT event thread.
  • Set a default window size before showing it, so there will not be a window of minimum size that I'm required to resize to use.
  • The nome field contains null when the class constructor is started. As a result, JTextField was of such a ridiculously small size that it was not usable.
  • You added JComboBox and JTextField to JPanel , but did not add JPanel to the screen. The result is a blank canvas!
  • It pays to put a legal layout on your JPanel . As it is, it's even hard to use.
  • As I mentioned before, I do not know what else should happen in recarregarTela . I put there System.out.println just to prove that it is called when it should actually be called.
  • If you want to make it simpler, if you are using Java 8 or higher, use a lambda:

        jComBox_NomeUsuar.addActionListener(event -> {
            String selected = (String) jComBox_NomeUsuar.getSelectedItem();
            if (selected.equalsIgnoreCase(txtLogin.getText())) {
                nome = selected;
                recarregarTela();
            }
        });
    

The question has been edited. Now my suggestion is to change this excerpt:

                for (cadastroBase load : cadTotal){
                    if (selected.equalsIgnoreCase(load.nomes)){
                        valCadBas.setLogin(load.login);
                        valCadBas.setPass(load.pass);
                        recarregarTela();
                    }
                }

So:

                for (cadastroBase load : cadTotal) {
                    if (selected.equalsIgnoreCase(load.nomes)) {
                        valCadBas.setLogin(load.login);
                        valCadBas.setPass(load.pass);
                        txtLogin.setText(load.login);
                        passSenha.setText(load.pass); // Isso só se você achar que faz sentido colocar a senha.
                        break;
                    }
                }

And with that, the recarregarTela() method ceases to exist.

    
15.04.2015 / 11:55