2017-04-04 18 views
0

我有一个自定义JLabel的实例,我想更改所有框架中的文本,但文本仅在最后打开的框架上更改。有一种方法可以实现这个目标?更新所有框架中的自定义JLabel

这里发生了什么: enter image description here

而且我的代码:

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()); 
    } 

} 

更新

这是什么现在即时通讯做的事我想要的。

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(); 
    } 

} 
+0

你想使用电汇的观察者设计模式的东西,所以当用户改变,所有注册的侦听器(这里的两个窗口 - 这应该是对话框,而不是JFrame--改变)。查找M-V-C或模型 - 视图 - 控制器是以全面的方式来构造这个结构的最佳方法,然后相应地重新构造程序。 –

+0

请参阅[使用多个JFrames,好/坏实践?](http://stackoverflow.com/q/9554636/418556) –

+0

@HovercraftFullOfEels我已经使用了观察者,现在能够做我想做的事。顺便说一句,即时更新代码。 –

回答

1

我有一个自定义的JLabel的情况下,我想改变其在所有帧中的文本,

一Swing组件只能有一个父对象。所以你实际上有两个自定义标签的实例。因此更新一个标签中的文本不会影响其他标签。

您可以做的是创建一个PlainDocument以包含要由多个JTextField共享的文本。然后当文本被更改时,所有文本字段都将被更新。

所以在App类,你将有:

private PlainDocument sharedDocument = new PlainDocument(); 

,你会创建访问Document的方法。也许像getSharedDocument()

然后在表单类,你会做这样的事情:

//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);