Observer-Beispiel Aufgabenstellung Aus einer Liste möglicher Farben soll jeweils eine Farbe auswählbar sein. Bei jeder Auswahländerung wird in einem Fenster die aktuelle Farbe dargestellt und in einem anderen Fenster der Zeitpunkt der Änderung festgehalten. UML-Diagramm Observable +observables <<Interface>> Observer Watch2Lists ColorFrame ListFrame ValidColors ConcreteSubject ConcreteObserver Observer ConcreteObserver Berufsakademie Stuttgart Objektorientiertes Software Engineering 2003 Seite 1 von 6
Code Anmerkung: Dieser Code wurde von Volker Wurst zur Verfügung gestellt. import java.util.observable; import java.util.vector; * Observer - Beispiel * Model-Klasse (d.h. das "Subject" im Observer-Pattern) public class ValidColors extends Observable{ private Vector colors = new Vector(); private String selectedcolor; public Vector getcolors() { return colors; public void setcolors(vector colors) { this.colors = colors; select((string) colors.firstelement()); public void addcolor(string colorname) { this.colors.add(colorname); select(colorname); public void select(string colorname) { this.selectedcolor = colorname; setchanged(); notifyobservers(colorname); Berufsakademie Stuttgart Objektorientiertes Software Engineering 2003 Seite 2 von 6
//------------------------------------------------------------------------ import java.awt.*; import javax.swing.*; import java.util.observable; import java.util.observer; * Observer - Beispiel * Observer-Klasse für die Klasse ValidColors * Ausgabe der ausgewählten Farbe und entsprechende Einfärbung des Fensters class ColorFrame extends JFrame implements Observer { Color color; String color_name = "black"; JPanel p = new JPanel(true); //-------------------------------------- public ColorFrame(ValidColors colors) { super("selected Color"); //set frame caption getcontentpane().add("center", p); colors.addobserver(this); //register with Subject setbounds(100, 100, 100, 100); setvisible(true); public void paint(graphics g) { g.drawstring(color_name, 20, 50); * @see java.util.observer#update(observable, Object) * setze Text und Farbe anhand des übergebenen TextStrings public void update(observable o, Object arg) { //Observer is notified of change here color_name = (String) arg; //save color name //set background to that color if (color_name.touppercase().equals("red")) color = Color.red; if (color_name.touppercase().equals("blue")) color = Color.blue; if (color_name.touppercase().equals("green")) color = Color.green; setbackground(color); Berufsakademie Stuttgart Objektorientiertes Software Engineering 2003 Seite 3 von 6
//---------------------------------------------------------------------- import java.awt.*; import java.util.date; import java.util.observable; import java.util.observer; import javax.swing.*; * Observer - Beispiel * Observer-Klasse für die Klasse ValidColors * Ausgabe der ausgewählten Farben mit dem zugehörigen Timestamp class ListFrame extends JFrame implements Observer { JList list; JPanel p; JScrollPane lsp; JListData listdata; public ListFrame(ValidColors colors) { super("color Selection History"); //put panel into the frmae p = new JPanel(true); getcontentpane().add("center", p); p.setlayout(new BorderLayout()); //Tell the Subject we are interested colors.addobserver(this); //Create the list listdata = new JListData(); //the list model list = new JList(listData); //the visual list lsp = new JScrollPane(); //the scroller lsp.getviewport().add(list); p.add("center", lsp); lsp.setpreferredsize(new Dimension(100, 100)); setbounds(250, 100, 300, 100); setvisible(true); * @see java.util.observer#update(observable, Object) * Füge die geänderte Farbe mit Timestamp zu der Liste hinzu public void update(observable o, Object arg) { listdata.addelement((string) arg + " (" + new Date().toString() + ")"); Berufsakademie Stuttgart Objektorientiertes Software Engineering 2003 Seite 4 von 6
//---------------------------------------------------------------------- import java.util.vector; import javax.swing.abstractlistmodel; /* * Modelklasse für die Klasse ListFrame zur Speicherung der Color-selections class JListData extends AbstractListModel { private Vector data; //the color name list public JListData() { data = new Vector(); public int getsize() { return data.size(); public Object getelementat(int index) { return data.elementat(index); //add string to list and tell the list about it public void addelement(string s) { data.addelement(s); fireintervaladded(this, data.size() - 1, data.size()); Berufsakademie Stuttgart Objektorientiertes Software Engineering 2003 Seite 5 von 6
//---------------------------------------------------------------------- import java.awt.*; import java.awt.event.*; import java.util.iterator; import javax.swing.*; public class Watch2Lists extends JFrame implements ActionListener, ItemListener { Button Close; JRadioButton red, green, blue; ValidColors colors = new ValidColors(); public Watch2Lists() { super("change two other frames"); // initialize the Model colors.addcolor("red"); colors.addcolor("green"); colors.addcolor("blue"); //add panel to content pane JPanel p = new JPanel(true); p.setlayout(new BorderLayout()); getcontentpane().add("center", p); //vertical box layout Box box = new Box(BoxLayout.Y_AXIS); p.add("center", box); //add the radio buttons ButtonGroup bgr = new ButtonGroup(); Iterator elements = colors.getcolors().iterator(); while (elements.hasnext()) { JRadioButton button; box.add(button = new JRadioButton((String) elements.next())); button.additemlistener(this); bgr.add(button); WindowListener l = new WindowAdapter() { public void windowclosing(windowevent e) { System.exit(0); ; addwindowlistener(l); //---------create observers--------- ColorFrame cframe = new ColorFrame(colors); ListFrame lframe = new ListFrame(colors); setbounds(150, 250, 100, 100); setvisible(true); /* @see java.awt.event.itemlistener#itemstatechanged(itemevent) public void itemstatechanged(itemevent e) { //responds to radio button clicks //if the button is selected, update the model if (e.getstatechange() == ItemEvent.SELECTED) colors.select(((jradiobutton) e.getsource()).gettext()); /* @see java.awt.event.actionlistener#actionperformed(actionevent) public void actionperformed(actionevent e) { public static void main(string[] arguments) { new Watch2Lists(); Berufsakademie Stuttgart Objektorientiertes Software Engineering 2003 Seite 6 von 6