Marco Gustavo
Marco Gustavo

Reputation: 69

Update a custom JLabel in all frames

I have a instance of a custom JLabel and i want to changes its text in all frames, but the text is changing only on the last opened frame. There's a way i can achieve this?

Here's what happens: enter image description here

And my code:

App.java

package test;

import javax.swing.JFrame;

public class App extends JFrame {

    protected static App app;

    private String loggedUser;
    private MyCustomLabel myCustomLabel;

    public App() {
        loggedUser = "User One";
        myCustomLabel = new MyCustomLabel(loggedUser);
    }

    public static App getApp() {
        return app;
    }

    public MyCustomLabel getMyCustomLabel() {
        return myCustomLabel;
    }

    public String getLoggedUser() {
        return loggedUser;
    }

    public void setLoggedUser(String loggedUser) {
        this.loggedUser = loggedUser;
    }

}

FrmApp.java

package test;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

/**
 *
 * @author Marco
 */
public class FrmApp extends App {

    public FrmApp() {
        app = new App();
        initComponents();
    }

    private void initComponents() {
        setLayout(new FlowLayout());
        setSize(300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        btnFrmOne = new JButton("Open frmOne");
        btnFrmOne.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                FrmOne frmOne = new FrmOne();
                frmOne.setVisible(true);
            }
        });
        add(btnFrmOne);

        btnFrmTwo = new JButton("Open frmTwo");
        btnFrmTwo.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                FrmTwo frmTwo = new FrmTwo();
                frmTwo.setVisible(true);
            }
        });
        add(btnFrmTwo);

        btnChangeUser = new JButton("Change user");
        btnChangeUser.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (App.getApp().getLoggedUser().equals("User One")) {
                    App.getApp().setLoggedUser("User Two");
                } else {
                    App.getApp().setLoggedUser("User One");
                }

                App.getApp().getMyCustomLabel().refresh();
            }
        });
        add(btnChangeUser);
    }

    private JButton btnFrmOne;
    private JButton btnFrmTwo;
    private JButton btnChangeUser;

    public static void main(String args[]) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(FrmApp.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(FrmApp.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(FrmApp.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(FrmApp.class.getName()).log(Level.SEVERE, null, ex);
        }

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FrmApp().setVisible(true);
            }
        });
    }

}

FrmOne.java

package test;

import java.awt.FlowLayout;
import javax.swing.JFrame;

public class FrmOne extends JFrame {

    public FrmOne() {
        initComponents();
    }

    private void initComponents() {
        setLayout(new FlowLayout());
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setSize(150, 100);

        add(App.getApp().getMyCustomLabel());
    }

}

FrmTwo.java

package test;

import java.awt.FlowLayout;
import javax.swing.JFrame;

public class FrmTwo extends JFrame {

    public FrmTwo() {
        initComponents();
    }

    private void initComponents() {
        setLayout(new FlowLayout());
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        setSize(150, 100);

        add(App.getApp().getMyCustomLabel());
    }

}

MyCustomLabel.java

package test;

import javax.swing.JLabel;

public class MyCustomLabel extends JLabel {

    public MyCustomLabel(String loggedUser) {
        initComponents(loggedUser);
    }

    private void initComponents(String loggedUser) {
        setText(loggedUser);
    }

    public void refresh() {
        setText(App.getApp().getLoggedUser());
    }

}

Update

This is what im doing now to do what i wanted.

App.java

public class App extends JFrame {

    public App() {
        User user = new User(1, "User One");
        LoggedUser.getInstance().setUser(user);

        initComponents();
    }

    public static void main(String[] args) {
        new App().setVisible(true);
    }

    private void initComponents() {
        setSize(200, 200);
        setLocation(400, 200);
        setLayout(new FlowLayout());
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JButton btn1 = new JButton("dlgOne");
        btn1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                DlgOne dlgOne = new DlgOne(App.this, false);
                dlgOne.setVisible(true);
            }
        });

        JButton btn2 = new JButton("dlgTwo");
        btn2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                DlgTwo dlgTwo = new DlgTwo(App.this, false);
                dlgTwo.setVisible(true);
            }
        });

        JButton btn3 = new JButton("change user");
        btn3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (LoggedUser.getInstance().getUser().getId() == 1) {
                    User user = new User(2, "User Two");
                    LoggedUser.getInstance().setUser(user);
                } else {
                    User user = new User(1, "User One");
                    LoggedUser.getInstance().setUser(user);
                }
            }
        });

        add(btn1);
        add(btn2);
        add(btn3);
    }
}

MyCustomPanel.java

public class MyCustomPanel extends JPanel implements Observer {

    private JLabel label;

    public MyCustomPanel() {
        initComponents();
    }

    @Override
    public void update(Observable o, Object arg) {
        //LoggedUser u = (LoggedUser) o;
        //System.out.println(u.getUser().getId());

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                label.setText(LoggedUser.getInstance().getUser().getName());
            }

        });
    }

    private void initComponents() {
        LoggedUser.getInstance().addObserver(this);

        label = new JLabel(LoggedUser.getInstance().getUser().getName());
        add(label);
    }

}

User.java

public class User {

    private int id;
    private String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

DlgOne.java

public class DlgOne extends JDialog {

    public DlgOne(Frame owner, boolean modal) {
        super(owner, modal);
        initComponents();
    }

    private void initComponents() {
        setTitle("dlgOne");
        setSize(200, 200);
        setLocation(600, 200);
        setLayout(new FlowLayout());
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        add(new MyCustomPanel());
    }

}

DlgTwo.java

public class DlgTwo extends JDialog {

    public DlgTwo(Frame owner, boolean modal) {
        super(owner, modal);
        initComponents();
    }

    private void initComponents() {
        setTitle("dlgTwo");
        setSize(200, 200);
        setLocation(800, 200);
        setLayout(new FlowLayout());
        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        add(new MyCustomPanel());
    }

}

LoggedUser.java

public class LoggedUser extends Observable {

    private static LoggedUser instance;

    public static LoggedUser getInstance() {
        if (instance == null) {
            instance = new LoggedUser();
        }

        return instance;
    }

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
        setChanged();
        notifyObservers();
    }

}

Upvotes: 0

Views: 237

Answers (1)

camickr
camickr

Reputation: 324108

I have a instance of a custom JLabel and i want to changes its text in all frames,

A Swing component can only have a single parent. So you actually have two instances of your custom label. So updating the text in one label does not affect the other.

What you can do is create a PlainDocument to contain the text to be shared by multiple JTextFields. Then when the text is the Document is changed all the text fields will be updated.

So in the App class you would have:

private PlainDocument sharedDocument = new PlainDocument();

and you would create a method to access the Document. Maybe something like getSharedDocument().

Then in the form classes you would do something like:

//add(App.getApp().getMyCustomLabel());
JTextField textField = new JTextField( App.getApp().getSharedDocument() );
//  customize text field to look like a label
textField.setBorder( null );
textField.setEditable( false );
add( textField );

Upvotes: 1

Related Questions