001package observer.gui; 002//[C] 2002 Sun Microsystems, Inc.--- 003import java.awt.BorderLayout; 004import java.awt.Container; 005import java.awt.GridLayout; 006import java.awt.event.ActionEvent; 007import java.awt.event.ActionListener; 008import java.awt.event.WindowAdapter; 009import java.awt.event.WindowEvent; 010import java.util.List; 011import java.util.ArrayList; 012 013import javax.swing.BoxLayout; 014import javax.swing.JButton; 015import javax.swing.JComboBox; 016import javax.swing.JFrame; 017import javax.swing.JLabel; 018import javax.swing.JPanel; 019import javax.swing.JScrollPane; 020import javax.swing.JTextArea; 021import javax.swing.JTextField; 022 023public class RunObserverPattern { 024 public static void main(String[] arguments) { 025 System.out.println("Example for the Observer pattern"); 026 System.out.println("This demonstration uses a central observable"); 027 System.out.println(" object to send change notifications to several"); 028 System.out.println(" JPanels in a GUI. Each JPanel is an Observer,"); 029 System.out.println(" receiving notifcations when there has been some"); 030 System.out.println(" change in the shared Task that is being edited."); 031 System.out.println(); 032 033 System.out.println("Creating the ObserverGui"); 034 ObserverGui application = new ObserverGui(); 035 application.createGui(); 036 } 037} 038 039class Task { 040 private String name = ""; 041 042 private String notes = ""; 043 044 private double timeRequired; 045 046 public Task() { 047 } 048 049 public Task(String newName, String newNotes, double newTimeRequired) { 050 name = newName; 051 notes = newNotes; 052 timeRequired = newTimeRequired; 053 } 054 055 public String getName() { 056 return name; 057 } 058 059 public String getNotes() { 060 return notes; 061 } 062 063 public double getTimeRequired() { 064 return timeRequired; 065 } 066 067 public void setName(String newName) { 068 name = newName; 069 } 070 071 public void setTimeRequired(double newTimeRequired) { 072 timeRequired = newTimeRequired; 073 } 074 075 public void setNotes(String newNotes) { 076 notes = newNotes; 077 } 078 079 public String toString() { 080 return name + " " + notes; 081 } 082} 083 084class TaskChangeObservable { 085 private List<TaskChangeObserver> observers = new ArrayList<TaskChangeObserver>(); 086 087 public void addTaskChangeObserver(TaskChangeObserver observer) { 088 if (!observers.contains(observer)) { 089 observers.add(observer); 090 } 091 } 092 093 public void removeTaskChangeObserver(TaskChangeObserver observer) { 094 observers.remove(observer); 095 } 096 097 public void selectTask(Task task) { 098 for (TaskChangeObserver o : observers) { 099 o.taskSelected(task); 100 } 101 } 102 103 public void addTask(Task task) { 104 for (TaskChangeObserver o : observers) { 105 o.taskSelected(task); 106 } 107 } 108 109 public void updateTask(Task task) { 110 for (TaskChangeObserver o : observers) { 111 o.taskChanged(task); 112 } 113 } 114} 115 116interface TaskChangeObserver { 117 public void taskAdded(Task task); 118 public void taskChanged(Task task); 119 public void taskSelected(Task task); 120} 121 122@SuppressWarnings("serial") 123class TaskEditorPanel 124extends JPanel implements ActionListener, TaskChangeObserver 125{ 126 private JPanel controlPanel, editPanel; 127 128 private JButton add, update, exit; 129 130 private JTextField taskName, taskNotes, taskTime; 131 132 private TaskChangeObservable notifier; 133 134 private Task editTask; 135 136 public TaskEditorPanel(TaskChangeObservable newNotifier) { 137 notifier = newNotifier; 138 createGui(); 139 } 140 141 public void createGui() { 142 setLayout(new BorderLayout()); 143 editPanel = new JPanel(); 144 editPanel.setLayout(new GridLayout(3, 2)); 145 taskName = new JTextField(20); 146 taskNotes = new JTextField(20); 147 taskTime = new JTextField(20); 148 editPanel.add(new JLabel("Task Name")); 149 editPanel.add(taskName); 150 editPanel.add(new JLabel("Task Notes")); 151 editPanel.add(taskNotes); 152 editPanel.add(new JLabel("Time Required")); 153 editPanel.add(taskTime); 154 155 controlPanel = new JPanel(); 156 add = new JButton("Add Task"); 157 update = new JButton("Update Task"); 158 exit = new JButton("Exit"); 159 controlPanel.add(add); 160 controlPanel.add(update); 161 controlPanel.add(exit); 162 add.addActionListener(this); 163 update.addActionListener(this); 164 exit.addActionListener(this); 165 add(controlPanel, BorderLayout.SOUTH); 166 add(editPanel, BorderLayout.CENTER); 167 } 168 169 public void setTaskChangeObservable(TaskChangeObservable newNotifier) { 170 notifier = newNotifier; 171 } 172 173 public void actionPerformed(ActionEvent event) { 174 Object source = event.getSource(); 175 if (source == add) { 176 double timeRequired = 0.0; 177 try { 178 timeRequired = Double.parseDouble(taskTime.getText()); 179 } catch (NumberFormatException exc) { 180 } 181 notifier.addTask(new Task(taskName.getText(), taskNotes.getText(), 182 timeRequired)); 183 } else if (source == update) { 184 editTask.setName(taskName.getText()); 185 editTask.setNotes(taskNotes.getText()); 186 try { 187 editTask 188 .setTimeRequired(Double.parseDouble(taskTime.getText())); 189 } catch (NumberFormatException exc) { 190 } 191 notifier.updateTask(editTask); 192 } else if (source == exit) { 193 System.exit(0); 194 } 195 196 } 197 198 public void taskAdded(Task task) { 199 } 200 201 public void taskChanged(Task task) { 202 } 203 204 public void taskSelected(Task task) { 205 editTask = task; 206 taskName.setText(task.getName()); 207 taskNotes.setText(task.getNotes()); 208 taskTime.setText("" + task.getTimeRequired()); 209 } 210} 211 212@SuppressWarnings("serial") 213class TaskHistoryPanel extends JPanel implements TaskChangeObserver { 214 private JTextArea displayRegion; 215 216 public TaskHistoryPanel() { 217 createGui(); 218 } 219 220 public void createGui() { 221 setLayout(new BorderLayout()); 222 displayRegion = new JTextArea(10, 40); 223 displayRegion.setEditable(false); 224 add(new JScrollPane(displayRegion)); 225 } 226 227 public void taskAdded(Task task) { 228 displayRegion.append("Created task " + task + "\n"); 229 } 230 231 public void taskChanged(Task task) { 232 displayRegion.append("Updated task " + task + "\n"); 233 } 234 235 public void taskSelected(Task task) { 236 displayRegion.append("Selected task " + task + "\n"); 237 } 238} 239 240@SuppressWarnings("all") 241class TaskSelectorPanel 242extends JPanel implements ActionListener, TaskChangeObserver 243{ 244 private JComboBox selector = new JComboBox(); 245 246 private TaskChangeObservable notifier; 247 248 public TaskSelectorPanel(TaskChangeObservable newNotifier) { 249 notifier = newNotifier; 250 createGui(); 251 } 252 253 public void createGui() { 254 selector = new JComboBox(); 255 selector.addActionListener(this); 256 add(selector); 257 } 258 259 public void actionPerformed(ActionEvent evt) { 260 notifier.selectTask((Task) selector.getSelectedItem()); 261 } 262 263 public void setTaskChangeObservable(TaskChangeObservable newNotifier) { 264 notifier = newNotifier; 265 } 266 267 public void taskAdded(Task task) { 268 selector.addItem(task); 269 } 270 271 public void taskChanged(Task task) { 272 } 273 274 public void taskSelected(Task task) { 275 } 276} 277 278class ObserverGui { 279 public void createGui() { 280 JFrame mainFrame = new JFrame("Observer Pattern Example"); 281 Container content = mainFrame.getContentPane(); 282 content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS)); 283 TaskChangeObservable observable = new TaskChangeObservable(); 284 TaskSelectorPanel select = new TaskSelectorPanel(observable); 285 TaskHistoryPanel history = new TaskHistoryPanel(); 286 TaskEditorPanel edit = new TaskEditorPanel(observable); 287 observable.addTaskChangeObserver(select); 288 observable.addTaskChangeObserver(history); 289 observable.addTaskChangeObserver(edit); 290 observable.addTask(new Task()); 291 content.add(select); 292 content.add(history); 293 content.add(edit); 294 mainFrame.addWindowListener(new WindowCloseManager()); 295 mainFrame.pack(); 296 mainFrame.setVisible(true); 297 } 298 299 private static class WindowCloseManager extends WindowAdapter { 300 public void windowClosing(WindowEvent evt) { 301 System.exit(0); 302 } 303 } 304}