import javax.swing.*; import java.util.*; import java.awt.*; import java.awt.event.*; /* ----------------------------- Model */ interface CounterModel { public int getValue(); } interface MutableCounterModel extends CounterModel { public void inc(); } class CounterModelImpl implements MutableCounterModel { private int v; public CounterModelImpl() {v=0;} public void inc() {v++;} public int getValue() {return v;} } /* ----------------------------- observable Wrapper of a MutableCounterModel */ class ObservableCounterModel extends Observable implements MutableCounterModel { private MutableCounterModel theModel; ObservableCounterModel(MutableCounterModel m) {theModel= m;} public int getValue() {return theModel.getValue();} public void inc() { theModel.inc(); setChanged(); } } /* ---------------------------------- controller */ class CounterController { private ObservableCounterModel counter; public CounterController(ObservableCounterModel c) { counter=c; } public void increment() { counter.inc(); counter.notifyObservers(); } public void doubleIncrement() { counter.inc(); counter.inc(); counter.notifyObservers(); } public void makeOdd() { if ( counter.getValue()%2 == 0 ) { counter.inc(); counter.notifyObservers(); } } } /* ----------------------------- View */ class CounterView extends JLabel implements Observer { private CounterModel theObservedCounter; public CounterView( ObservableCounterModel m) { m.addObserver(this); theObservedCounter=m; /* da ora in poi solo l'interfaccia immutable del modello e' usata */ update(null,null); } public void update(Observable dummy1, Object dummy2) { int v=theObservedCounter.getValue(); String s= new Integer(v).toString(); setText(s); repaint(); } } class IncrementAction extends AbstractAction { private CounterController c; public IncrementAction(CounterController c1) { super("Incremento"); c=c1; } public void actionPerformed(ActionEvent e) {c.increment();} } class DoubleIncrementAction extends AbstractAction { private CounterController c; public DoubleIncrementAction(CounterController c1) { super("Doppio incremento"); c=c1; } public void actionPerformed(ActionEvent e) {c.doubleIncrement();} } class MakeOddAction extends AbstractAction { private CounterController c; public MakeOddAction(CounterController c1) { super("Rendi dispari"); c=c1; } public void actionPerformed(ActionEvent e) {c.makeOdd();} } class LockUnlockAction extends AbstractAction { private Action c; private void updateName() { if ( c.isEnabled() ) putValue(Action.NAME, "Lock"); else putValue(Action.NAME, "Unlock"); } public LockUnlockAction(Action c1) { c=c1; updateName(); } public void actionPerformed(ActionEvent e) { c.setEnabled(!c.isEnabled()); updateName(); } } class CounterComplexView extends JPanel { private CounterView cv; public CounterComplexView(ObservableCounterModel m, CounterController c) { cv= new CounterView(m); setLayout(new GridLayout(5,1)); add(cv); Action a=new IncrementAction(c); add(new JButton(a)); add(new JButton(new DoubleIncrementAction(c))); add(new JButton(new MakeOddAction(c))); add(new JButton(new LockUnlockAction(a))); } } /* ------------------------------------------ Application --- */ public class MvcDemo { public static void main(String args[]) { // Model ObservableCounterModel m1= new ObservableCounterModel(new CounterModelImpl()); // Controller CounterController c1=new CounterController(m1); // View CounterComplexView v1=new CounterComplexView(m1,c1); // Model ObservableCounterModel m2= new ObservableCounterModel(new CounterModelImpl()); // Controller CounterController c2=new CounterController(m2); // View CounterComplexView v21=new CounterComplexView(m2,c2); CounterComplexView v22=new CounterComplexView(m2,c2); // GUI setup JFrame f= new JFrame(); f.getContentPane().setLayout(new GridLayout(1,2)); f.getContentPane().add(v1); f.getContentPane().add(v21); f.getContentPane().add(v22); f.pack(); f.setVisible(true); } }