|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Senior Member
Iscritto dal: Feb 2007
Città: Verona
Messaggi: 1060
|
[Java] Design degli eventi
Ho scritto a scopo didattico un'applicazione desktop per il tris, human vs. cpu
![]() Ho fatto un disegno classi che definisco decente, forse troppo elaborato, ma a scopo didattico. In sintesi, così formata: alcune enum Codice:
public enum Player { HUMAN("X"), CPU("O"), NONE(" "); Player(String s) { this.s = s; } private String s; @Override public String toString() { return s; } } Codice:
public enum TrisState { HUMAN_WON("Human player won!"), CPU_WON("Cpu player won!"), DRAW("Draw!"), INCOMLETE("Your turn..."); TrisState (String label) { this.label = label; } private String label; @Override public String toString() { return this.label; } } Codice:
public class TrisGridModel extends AbstractTableModel { private Player[][] grid; public TrisGridModel() {...} public TrisGridModel(Player[][] grid) {...} public int getRowCount() {...} public int getColumnCount() {...} public Player getValueAt(int r, int c) {...} @Override public void setValueAt(Object aValue, int r, int c) {...} public TrisState getState() {...} public boolean complete() {...} public Player tris() {...} private void switchNow() {...} //Ecco la gestione degli eventi private List<TrisGameListener> listeners; { this.listeners = new ArrayList<TrisGameListener>(); } public void addTrisGameListener (TrisGameListener tgl) {...} public boolean removeTrisGameListener (TrisGameListener tgl) {...} private void fireTrisGameEvent (TrisGameEvent tge) { //TODO notifica dell'evento ... } } Codice:
public interface TrisGameListener extends java.util.EventListener { public void movePerformed (TrisGameEvent tge); public void stateChanged (TrisGameEvent tge); } vorrei progettare una gestione degli eventi in perfetto stile Swing, con eventi, ascoltatori e oggetti che generano eventi. Però non ho capito bene come si deve definire la classe che descrive un evento. Nel caso sopra (TrisGameListener) ci sono due possibili tipi di evento: - un giocatore inserisce un simbolo (movePerformed(...)) - la griglia cambia di stato (vedi TrisGameState) (stateChanged(...)) Cosa devo scrivere nella classe TrisGameEvent? I metodi dell'ascoltatore che parametri devono prendere in ingresso? L'interfaccia grafica comunica con la griglia (TrisGameModel) tramite gli eventi caratteristici della classe TableModel, infatti, nella classe della gui: Codice:
public class TrisPanel extends JPanel { private JButton[][] grid; private TrisGridModel model; public TrisPanel () {...} public TrisPanel(TrisGridModel model) { this.model = model; this.model.addTableModelListener( new TrisModelListener() ); ... } public class TrisModelListener implements TableModelListener { public void tableChanged(TableModelEvent e) {...} } } Altro dubbio: se ho un oggetto Swing con alcuni ascoltatori registrati ad esso, una volta che genera un evento e attiva i metodi degli ascoltatori, qual'è il thread in esecuzione? Posso agire su oggetti Swing direttamente oppure devo usare l'invokeLater() ??
__________________
|
![]() |
![]() |
![]() |
#2 | |||
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
Ad esmepio, il listener su cui viene invocato il metodo statChanged() sarà interessato a recuperare quello stato, per esaminarlo, percui il tuo TrisGameEvent potrebbe avere un membro di tipo TrisState e un metodo getter. Nel caso di movePerformed() non so cosa possa interessare: se movePerformed rappresenta l'evento che accade quando un giocatore inserisce un simbolo potrebbe essere utile sapere quale istanza Palyer della griglia è cambiata e che valore ha. Il valore lo si ricava dall'istanza Player stessa (codifica una String e ha ridefinito un toString() che la restituisce, e questa stringa rappresenta il suo valore). L'istanza Player cambiata è identificata dalla sua posizione nella griglia, ovvero dai due indici che la identificano nell'array bidimensionale del TrisGridModel: perciò potrebbe essere utile, per l'ascoltatore, poter chiedere a TrisGameEvent la posizione dell'istanza Player cambiata. Quote:
Quote:
Puoi vedere quale thread stia eseguendo un certo pezzo di codice chiamando Thread.currentThread() che torna una reference al thread corrente ![]()
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) Ultima modifica di banryu79 : 03-11-2009 alle 11:30. |
|||
![]() |
![]() |
![]() |
#3 | |
Senior Member
Iscritto dal: Feb 2007
Città: Verona
Messaggi: 1060
|
Quote:
Scusami se non ho risposto subito, ho avuto da fare, ma il 3d rimane sempre aperto. Ho inserito le modifiche nel codice sorgente e questo è quello che ho ottenuto: Classe TrisGameEvent Codice:
public class TrisGameEvent extends java.awt.AWTEvent { public static final int MOVE_PERFORMED = RESERVED_ID_MAX + 1; public static final int STATE_CHANGED = RESERVED_ID_MAX + 2; private int row; private int column; private Player player; private TrisState state; public TrisGameEvent(Object source, int type, int row, int column) { super(source, type); this.row = row; this.column = column; } public TrisGameEvent (Object source, int type, int row, int column, TrisState state) { this(source, type, row, column); this.state = state; } public TrisGameEvent(Object source, int type, int row, int column, Player player) { this(source, type, row, column); this.player = player; } public int getRow() { return row; } public int getColumn() { return column; } public TrisState getState() { return state; } } Codice:
public class TrisGridModel extends AbstractTableModel { private Player[][] grid; private Player now; private TrisState prevState; public TrisGridModel() {...} public TrisGridModel(Player[][] grid) {...} public int getRowCount() {...} public int getColumnCount() {...} public Player getValueAt(int r, int c) { return this.grid[r][c]; } public void setValueAt(Object aValue, int r, int c) { if (this.now == Player.NONE) return; if (r < this.getRowCount() && c < this.getColumnCount() && aValue instanceof Player) { if ( (Player)aValue == this.now ) { this.grid[r][c] = this.now; this.switchNow(); this.fireMovePerformed(r, c, (Player) aValue); } } //FIXME else lancia una BRUTTA eccezione } public TrisState getState() {...} public boolean complete() {...} public Player tris() {...} private TrisGameListener listener; public void addTrisGameListener (TrisGameListener tgl) { listener = TrisGameEventMulticaster.add(listener, tgl); } public void removeTrisGameListener (TrisGameListener tgl) { listener = TrisGameEventMulticaster.remove(listener, tgl); } private void fireMovePerformed(int row, int column, Player player) { this.listener.movePerformed( new TrisGameEvent(this, TrisGameEvent.MOVE_PERFORMED, row, column, player) ); this.fireTableCellUpdated(row, column); if (this.getState() != this.prevState) { this.prevState = this.getState(); this.fireStateChanged(row, column, prevState); } } private void fireStateChanged(int row, int column, TrisState state) { this.listener.stateChanged( new TrisGameEvent(this, TrisGameEvent.STATE_CHANGED, row, column, state) ); } }
__________________
|
|
![]() |
![]() |
![]() |
#4 |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Beh, mi pare di sì.
A te la cosa funziona? ![]()
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Feb 2007
Città: Verona
Messaggi: 1060
|
Devo ancora utilizzarlo
![]() Mi interessava la correttezza "logica"
__________________
|
![]() |
![]() |
![]() |
#6 | |
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
Se quello che cercavi era un cosiglio per implementare "in modo idiomatico" il tuo modello ad eventi allora non dare retta a quello che ti ho detto: ne so quanto te ![]()
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 21:50.