2017-04-04 16 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);