|
|||||||
|
|
|
![]() |
|
|
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 12: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: 01:48.




















