Reputation: 69
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?
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
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