Das Problem der Verbindung der Lauscher mit allen Views
erfordert ein generisches MVC-Konzept. Die Idee dabei ist, dass ein
enum alle Ereignisse aufzählt, die von einer Oberfläche kommen
können. Zu jedem Ereignis wird ein
Lauscher-Objekt zugeordnet, deren
einzige Methode aktion()
auf dieses Ereignis reagiert. Diese Zuordnung kann z.B. in einer
Map erfolgen.
Die setLauscher-Methode
von IView
bekommt als Parameter so ein
Map:
package uhrMVC;
import
java.util.Map;
public
interface IView {
enum Ereignis {
EIN, AUS,
UM }
static
interface Lauscher {
void aktion(); }
void setLauscher(Map<Ereignis, Lauscher>
lauscher);
void
tick();
void
start();
void
stopp(); }
Im Konstruktor des für alle Views gemeinsamen Controls wird
das Map-Objekt
erzeugt und allen Views übergeben:
public Control(final
IModel model, final IView[] views) {
Map<Ereignis, Lauscher>
lauscher =
lauscher.put(Ereignis.EIN,
new Lauscher() {
@Override
public
void aktion() {
model.start();
for
(IView view : views)
view.start(); } });
lauscher.put(Ereignis.AUS,
new Lauscher() {
@Override
public
void aktion() {
model.stopp();
for
(IView view : views)
view.stopp(); } });
lauscher.put(Ereignis.UM,
new Lauscher() {
@Override
public
void aktion() {
model.umschalten(); } });
for
(IView view : views)
view.setLauscher(lauscher);
new Thread() { … // wie gehabt
Jede View bekommt also alle Lauscher und fügt selber ihrer
Darstellung hinzu:
public
class DigitalView
extends JFrame
implements IView
{
…
@Override
public
void setLauscher(final
Map<Ereignis, Lauscher> lauscherMap) {
knopfEin.addActionListener(new
ActionListener() {
@Override
public
void
actionPerformed(ActionEvent e) {
lauscherMap.get(Ereignis.EIN).aktion();
} });
knopfAus.addActionListener(new
ActionListener() {
@Override
public
void
actionPerformed(ActionEvent e) {
lauscherMap.get(Ereignis.AUS).aktion();
} });
knopfUm.addActionListener(new
ActionListener() {
@Override
public
void
actionPerformed(ActionEvent e) {
lauscherMap.get(Ereignis.UM).aktion();
} }); }
sowie
public
class KreisView
extends JFrame
implements IView
{
…
@Override
public
void setLauscher(final
Map<Ereignis, Lauscher> lauscherMap) {
super.addKeyListener(new
KeyAdapter() {
@Override
public
void
keyPressed(KeyEvent e) {
switch
(e.getKeyChar()) {
case
'E':
// "Ein"
lauscherMap.get(Ereignis.EIN).aktion();
break;
case
'A': // "Aus"
lauscherMap.get(Ereignis.AUS).aktion();
break;
case
'U': // "Um"
lauscherMap.get(Ereignis.UM).aktion();}
} }); } }
In
main wird nun
Control mit einer Reihung aus
allen Views instanziiert:
public
static
void
main(String[] args) {
IModel model =
new
Model();
new
Control(model,
new
IView[] {
new
KreisView(model),
new
DigitalView(model) }); }
Wenn Views dynamisch (zur Laufzeit) hinzugefügt werden
können sollen, muss man statt der Reihung
ArrayList benutzen.
Version: 19. April 2012
© Prof. Solymosi, 20102 Beuth-Hochschule für Technik Berlin, Fachbereich VI (Informatik und Medien)
solymosibht-berlin.de