Update (refresh) a Jdialog (swing) dynamically

Asked

Viewed 1,525 times

1

I’m having some problems updating the JDialog created through the WindowsBuilder no Eclipse (would not be on account of this).

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

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

Below an excerpt 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 this case, my method would do more or less what is up there, but with some extra fields and internal methods that run in other classes. But the way it is, it doesn’t work.

To see if I can communicate better: I have the screen (generated by the eclipse Windows) that initially displays the data of the user who logged on to the system (let’s assume login and password) via get/set and the other information of all users that it has access to saved in an array by only loading the logins in jcombobox, then when it modifies some house in the combobox I validate if what it changes in jcombobox is different than the one shown on the screen, if yes I load this user information in get/set and try to give refresh of the page by the methods revalidate() and repaint() by which they do not update the register (the compiler java running both but nothing happens next). In case you need the whole code I have it tomorrow because today I am not at home.

  • 2

    Hi Giovan, welcome to Stack Overflow. In order for us to help you we need a bigger context about what’s happening and what’s not working. Create a mvce and we started working from there.

  • 1

    This code does not run, with syntax error. Try to test the code posted before creating the question.

1 answer

1


The best I could do was this. I don’t know what he was supposed to do exactly when he reloaded the screen, so I put a System.out.println to demonstrate that the method was called. Whenever I select in JComboBox a name similar to that of JTextField, this function is called and the text is written in the console.

Here’s 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 his code there were the following problems:

  • You were using protect instead of protected, this caused a compilation error (as revised by Bruno César).
  • Some were missing Casts when using the method getSelectedItem() of JComboBox. This also caused a build error.
  • You haven’t given the whole class, which obviously makes your code noncompilable and makes your question harder to answer. It took me a while to realize that altCadastroUsuario was the class name. However, I shouldn’t have to guess this alone. Also, 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 displaying it, so I don’t see a minimum window size that I have to resize to use.
  • The field nome contains null when the class constructor is started. As a result, the JTextField had a size so ridiculously small, she wasn’t wearable.
  • You added to JComboBox and the JTextField in a JPanel, but did not add the JPanel to the screen. The result is that a blank screen was coming!
  • It is worth you to give a lunge to put a cool layout in your JPanel. The way it is, it’s hard to use.
  • As I mentioned before, I don’t know what else should happen at recarregarTela. I put a System.out.println only to prove that he is called when he should indeed be called.
  • If you want to make it simpler, if you’re 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 exchange this excerpt:

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

That’s why:

                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 method recarregarTela() cease to exist.

  • How are you using method referece capture, Instead of using an anonymous class in Software consider using lambda with an Handler method, I think it would be more "readable". Maybe it’s also good to make it clear that you’re using java 8 =)

  • 1

    @Brunocésar Feito.

  • Dear Good Morning, Thank you for the help, the above code is just a sketch and sorry I didn’t put all, validating information together with 5 classes on this screen which ends up making it a little difficult to explain the code, what I’m trying to do is in the comment below to understand, but in fact it would be a refresh on the screen reloading the information.

  • I have the screen (generated by the eclipse windows) that initially displays the data of the user who logged on to the system (let’s assume login and password) via get/set and load the other users in an array passing to the screen only the logins in the 'jcombobox', dai when it modifies some house in the combobox I validate if the current one is different from the one shown on the screen, if it is I load from the array the information of this user in the get/set and try to give the page refresh with revalidate() and repaint() without success (Java compiling executes both methods but nothing happens when going through them).

  • @Giovandias All you have to do is call the methods setText (or similar) in suitable objects, probably JLabels and JTextFields. It should not be necessary revalidate() and neither repaint().

  • Hello Victor, Thanks for the return. So I create the screen and display the JLabels and JTextFields with the user information that is logged in to the system, but when it exchanges the user that is in the JComboBox I have to update the information shown in JTextFields with the data of that other user (to understand, I, Giovan Me soon on the system, when I load the screen it is already created with my information, but I want to change the password of Victor who is another user, so I select his name in JComboBox and I have to update the screen information) if close and reopen the screen

  • @Giovandias Yes, you take this information that is the selected user, search all the necessary data with it, and then give the setText in all relevant fields of the screen.

  • @Victorstafusa I gave a great improvement in the code of the original post just do not notice the icons scattered in the frame, I hid the other icons. Just to indicate the registration classBase has the fields that the screen shows (all) and the get/set methods I use. Remember also that the arraylist of this screen has been adapted, it is saved on another screen and I load the information in it not to lose the information in case the screen der refresh, another point to be observed, when I create the screen I load the information I valid so that the refresh does not load the same information!!!!!

  • @Giovandias I edited my answer.

  • @Victorstafusa understood the question, but this information is loaded in a second class (I do not do direct functions on screens, work with 4 packages,!

  • @Okay Giovandias, but somewhere you’ll have to call the methods setText(), right?

  • @Victorstafusa Yes, tea already does this automatically in this part below: txtLogin.setText(valCadBas.getLogin()); contentPanel.add(txtLogin); passSenha.setText(valCadBas.getPass()); contentPanel.add(passNow);

  • @Victorstafusa I found the mistake and thank you for your explanation!!!! I made a setText() same and a repaint() and modified, now I will make a function that sets all the values at once to reuse the code and do when I create and when and update the code!!!! I really appreciate the explanation!!!!!!!!!!

Show 8 more comments

Browser other questions tagged

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