package observer.pattern;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Observable;
import java.util.Observer;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import observer.CourseRecord;
/**
* Presents a given view of a set of courses and their marks. Uses the Observer
* pattern to be notified when a new course has been added.
*/
@SuppressWarnings("serial")
public class CourseController extends JPanel implements Observer, ChangeListener, ActionListener {
/**
* Constructs a CourseController object
*
* @param courses
* a set of courses and their marks
*/
public CourseController(CourseData courses) {
this.courseData = courses;
this.sliders = new Vector<JSlider>();
this.setLayout(new GridBagLayout());
this.setBackground(Color.white);
coursePanel = new JPanel();
coursePanel.setBorder(new TitledBorder("Courses"));
coursePanel.setLayout(new GridLayout(0, 1));
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.BOTH;
courses.addObserver(this);
Vector<CourseRecord> state = courses.getUpdate();
for (int i = 0; i < state.size(); i++)
this.addCourse(state.elementAt(i));
JScrollPane scrollPane = new JScrollPane(coursePanel,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
JButton button = new JButton("New Courses");
button.addActionListener(this);
constraints.weightx = 0.5;
constraints.weighty = 1.0;
constraints.gridx = 0;
constraints.gridy = 0;
this.add(scrollPane, constraints);
constraints.weightx = 0.5;
constraints.weighty = 0;
constraints.gridy = 1;
this.add(button, constraints);
}
/**
* Add a new course
*
* @param record
* the new course record to be added
*/
public void addCourse(CourseRecord record) {
JSlider slider = new JSlider();
slider.setBackground(Color.white);
slider.setName(record.getName());
slider.setValue(record.getNumOfStudents());
slider.setMinimum(0);
slider.setMaximum(100);
slider.setMajorTickSpacing(25);
slider.setMinorTickSpacing(5);
slider.setPaintTicks(true);
slider.setPaintLabels(true);
slider.setBorder(new TitledBorder(record.getName()));
slider.addChangeListener(this);
coursePanel.add(slider);
coursePanel.revalidate();
sliders.addElement(slider);
}
/**
* Informs this CourseController that a new course has been added
*
* @param o
* the CourseData subject that has changed
*/
public void update(Observable o, Object arg) {
CourseData courses = (CourseData) o;
Vector<CourseRecord> newCourses = courses.getUpdate();
for (int i = sliders.size(); i < newCourses.size(); i++) {
this.addCourse((CourseRecord) newCourses.elementAt(i));
}
}
/**
* Manages the creation of a new course. Called when the "New Course" button is pressed.
*
* @param arg0
* not used
*/
public void actionPerformed(ActionEvent arg0) {
String input = JOptionPane.showInputDialog("Please enter new course name:");
if (input != null){
courseData.addCourseRecord(new CourseRecord(input, 50));
// leave it up notify/update mechanism to invoke this.addCourse
}
}
/**
* Handles the changing of the marks for a course (changing of a JSlider)
*
* @param arg0
* the JSlider that has changed
*/
public void stateChanged(ChangeEvent arg0) {
JSlider slider = (JSlider) arg0.getSource();
courseData.changeCourseRecord(slider.getName(), slider.getValue());
}
/**
* Sets up an initial set of three courses
*
* @param args
* not used
*/
public static void main(String[] args) {
CourseData data = new CourseData();
data.addCourseRecord(new CourseRecord("Physics", 50));
data.addCourseRecord(new CourseRecord("Chemistry", 50));
data.addCourseRecord(new CourseRecord("Biology", 50));
CourseController controller = new CourseController(data);
BarChartObserver bar = new BarChartObserver(data);
JScrollPane scrollPane = new JScrollPane(bar,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JFrame frame = new JFrame("Observer Pattern");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new GridBagLayout());
frame.setResizable(false);
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.BOTH;
constraints.weightx = 0.25;
constraints.weighty = 1.0;
constraints.gridx = 0;
constraints.gridy = 0;
frame.getContentPane().add(controller, constraints);
constraints.weightx = 0.5;
constraints.weighty = 1.0;
constraints.gridx = 1;
constraints.gridy = 0;
frame.getContentPane().add(scrollPane, constraints);
frame.pack();
frame.setVisible(true);
}
private CourseData courseData;
private Vector<JSlider> sliders;
private JPanel coursePanel;
}