Would someone be kind enough to look at this simple program and tell me what's wrong with the implementation of the Observer design pattern?
When I run it, nothing shows up in the table (was showing before the implementation).
I'm just starting to learn design patterns so I'm not sure how to debug it.
My teacher gave us this example of a program with Observer design pattern... and it doesn't seem to work!
The program is just data in data out in a jTable.
I thank you in advance –> here's the complete code
Here is the data entry GUI:
package com.employe.listing;
import java.util.ArrayList;
public class addEmployeJFrame extends javax.swing.JFrame {
ArrayList<addEmployeJFrameObserver> observers = new ArrayList<>();
public addEmployeJFrame() {
initComponents();
}
public synchronized void addAddEmployeJFrameObserver(addEmployeJFrameObserver observer) {
observers.add(observer);
}
public synchronized void removeAddEmployeJFrameObserver(addEmployeJFrameObserver observer) {
observers.remove(observer);
}
public synchronized void notifyAddEmployeJFrameObserver(Employe e) {
for(addEmployeJFrameObserver o : observers) {
o.NotifyAddEmployeJFrame(e);
}
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Employe employe = new Employe();
employe.setName(jTextField1.getText());
employe.setJob(jTextField2.getText());
employe.setSalary(Integer.parseInt(jTextField3.getText()));
employe.setYearsAtWork(Integer.parseInt(jTextField4.getText()));
notifyAddEmployeJFrameObserver(employe);
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JLabel jLabel4;
private javax.swing.JLabel jLabel5;
private javax.swing.JLabel jLabel6;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;
private javax.swing.JTextField jTextField3;
private javax.swing.JTextField jTextField4;
// End of variables declaration
}
Here is the controller:
package com.employe.listing;
import java.util.ArrayList;
public class Controller implements addEmployeJFrameObserver {
ArrayList<Employe> employes = new ArrayList<>();
ArrayList<ListingEmployesJFrameObserver> observers = new ArrayList<>();
addEmployeJFrame EmployeJFrame;
ListingEmployesJFrame listingJFrame;
public Controller() {
listingJFrame = new ListingEmployesJFrame();
EmployeJFrame = new addEmployeJFrame();
EmployeJFrame.addAddEmployeJFrameObserver(this);
listingJFrame.setVisible(true);
EmployeJFrame.setVisible(true);
}
public synchronized void addListingEmployesJFrameObserver(ListingEmployesJFrameObserver o) {
observers.add(o);
}
public synchronized void removeListingEmployesJFrameObserver(ListingEmployesJFrameObserver o) {
observers.remove(o);
}
public synchronized void notifyListingEmployesJFrameObserver(ArrayList<Employe> employes) {
for(ListingEmployesJFrameObserver o : observers) {
o.notifyListingEmployesJFrame(employes);
}
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Controller controler = new Controller();
}
public void addEmploye(Employe employe) {
employes.add(employe);
notifyListingEmployesJFrameObserver(employes);
}
public ArrayList<Employe> getListEmployee() {
return employes;
}
@Override
public void NotifyAddEmployeJFrame(Employe e) {
this.addEmploye(e);
}
}
and here's the jTable (data out):
package com.employe.listing;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
public class ListingEmployesJFrame extends javax.swing.JFrame implements ListingEmployesJFrameObserver {
ArrayList<Employe> employes = new ArrayList<>();
/**
* Creates new form ListingEmployesJFrame
*/
public ListingEmployesJFrame() {
initComponents();
AbstractTableModel model = new AbstractTableModel() {
@Override
public String getColumnName(int column) {
if(column == 0) {
return "Name";
} else if(column == 1) {
return "Job";
} else if(column == 2) {
return "Salary";
} else {
return "Years";
}
}
@Override
public int getRowCount() {
return employes.size();
}
@Override
public int getColumnCount() {
return 4;
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
if(columnIndex == 0) {
return employes.get(rowIndex).getName();
} else if(columnIndex == 1) {
return employes.get(rowIndex).getJob();
} else if(columnIndex == 2) {
return employes.get(rowIndex).getSalary();
} else {
return employes.get(rowIndex).getYearsAtWork();
}
}
};
jTable1.setModel(model);
}
// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1;
// End of variables declaration
@Override
public void notifyListingEmployesJFrame(ArrayList<Employe> employes) {
this.employes = employes;
jTable1.updateUI();
}
}
I don't see anywhere in your code where you are calling
addListingEmployesJFrameObserver()
to register an observer, so there are none to notify.Update the constructor of your
Controller.java
as show below:Edit: It's worth pointing out that calling
addListingEmployesJFrameObserver()
isn't a recommended practice. See What's wrong with overridable method calls in constructors? for more explaination.