I've followed this example to create a simple Swing MVC application: https://stackoverflow.com/a/16850977/1966873
I'm using Eclipse Luna with WindowBuilder.
There is a lot of code that must be duplicated every time I add a new field to the Model, such as
public void setName(String name) {
String old = this.name;
this.name = name;
spcs.firePropertyChange("name", old, name);
}
and
@Override
public void propertyChange(PropertyChangeEvent evt) {
String propName = evt.getPropertyName();
Object newVal = evt.getNewValue();
if("name".equalsIgnoreCase(propName)){
view.getLblTest().setText((String)newVal);
}
}
Is there any way for me to automatically generate these whenever I add a new field to the Model? Or is there another way to achieve what I want, which is to bind the model to the view.
The full sample application that I've created based on that answer:
Model.java
public class Model {
private SwingPropertyChangeSupport spcs;
private String name;
public Model(){
spcs = new SwingPropertyChangeSupport(this);
}
public void addPropertyChangeListener(PropertyChangeListener listener){
spcs.addPropertyChangeListener(listener);
}
public String getName() {
return name;
}
public void setName(String name) {
String old = this.name;
this.name = name;
spcs.firePropertyChange("name", old, name);
}
}
View.java
public class View {
private JFrame frame;
private JPanel panel;
private JLabel lblTest;
private JButton btnClickMe;
public View() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
initialize();
frame.setVisible(true);
}
});
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout(0, 0));
frame.getContentPane().add(getPanel(), BorderLayout.CENTER);
}
public JPanel getPanel() {
if (panel == null) {
panel = new JPanel();
panel.setLayout(new MigLayout("", "[][][][][][][][][]", "[][][]"));
panel.add(getBtnClickMe(), "cell 6 2");
panel.add(getLblTest(), "cell 8 2");
}
return panel;
}
public JLabel getLblTest() {
if (lblTest == null) {
lblTest = new JLabel("Test");
}
return lblTest;
}
public JButton getBtnClickMe() {
if (btnClickMe == null) {
btnClickMe = new JButton("Click me");
}
return btnClickMe;
}
}
Controller.java
public class Controller implements PropertyChangeListener{
private Model model;
private View view;
public Controller(Model model, View view){
this.model = model;
this.view = view;
this.model.addPropertyChangeListener(this);
setUpViewEvents();
}
private void setUpViewEvents(){
view.getBtnClickMe().addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
model.setName("John Smith");
}
});
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
String propName = evt.getPropertyName();
Object newVal = evt.getNewValue();
if("name".equalsIgnoreCase(propName)){
view.getLblTest().setText((String)newVal);
}
}
}
Main.java to start the program
public class Main {
public static void main(String[] args) {
Model model = new Model();
View view = new View();
Controller controller = new Controller(model, view);
}
}