Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Hyundai Ioniq 9: dopo due settimane di test non avremmo voluto restituirla
Hyundai Ioniq 9: dopo due settimane di test non avremmo voluto restituirla
Una ammiraglia elettrica, da sei o sette posti, con il comfort di viaggio come missione assoluta. Un'auto non per tutti, ma di cui ti innamori dopo pochi giorni, ecco com'è andata la nostra prova di lunga durata
LG UltraGear evo GM9: 27 pollici, 5K, Mini LED e Dual Mode
LG UltraGear evo GM9: 27 pollici, 5K, Mini LED e Dual Mode
Hyper Mini LED con 2.304 zone, DisplayPort 2.1 e Dual Mode: 5K a 165 Hz oppure QHD a 330 Hz: LG propone un monitor da gioco ma dalla buona versatilità creativa, con prestazioni interessanti e un listino di 1.220 euro. Peccato l'alimentatore ingombrante
Motorola edge 70 Fusion FIFA World Cup 26 Edition: un ottimo smartphone per i fan del calcio
Motorola edge 70 Fusion FIFA World Cup 26 Edition: un ottimo smartphone per i fan del calcio
Motorola edge 70 Fusion FIFA World Cup 26 Edition porta la maglia iridata su uno smartphone accessibile: display Extreme AMOLED da 6,78 pollici a 144Hz, fotocamera Sony LYTIA 710 con moto ai, Snapdragon 7s Gen 3 abbinato a 8GB di RAM, batteria da 5200 mAh con ricarica TurboPower a 68W e certificazione IP68/IP69, il tutto in una veste PANTONE Silhouette con logo dorato a 24 carati, moto buds bass incluse in confezione e contenuti software dedicati ai Mondiali 2026
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 23-09-2006, 18:53   #1
foxmolder5
Senior Member
 
Iscritto dal: Dec 2001
Messaggi: 2514
[JAVA] architettura multistrato e ActionListener

devo realizzare un programma in Java avente architettura multistrato ( tipo MVC ma con diverse semplificazioni) e sto riscontrando qualche grattacapo con la suddivisione delle competenze tra i vari strati. ho un strato "applicazione" in cui saranno presenti tutte le classi di "controllo" e poi uno strato superiore che costituisce l'interfaccia del software.
ho realizzato tale interfaccia, però non so come gestire l'ActionListener associato alla finestra che ho creato.
infatti quando viene attivato l'actionListener, viene solitamente eseguito il codice al suo interno, però tale codice, contenendo tutta la logica di gestione delle azioni, nel mio caso dovrà trovarsi all'interno della classe di controllo e non in quella di interfaccia.
una possibile soluzione sarebbe quella di inserire l'actionListener nella classe dell'interfaccia e, al momento della decisione dell'azione da fare, far ritornare il controllo alla classe di controllo (che ha chiamato quella di interfaccia) passando una struttura con tutti i dati al suo interno.
questa soluzione mi sembra 1 pò sporca e quindi vorrei sapere se esiste qualcosa di + pulito o se mi consigliate altro visto che sono abbastanza inesperto in questo campo. grazie
foxmolder5 è offline   Rispondi citando il messaggio o parte di esso
Old 24-09-2006, 13:21   #2
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
La soluzione è unica, se parliamo di architettura Modello-Vista-Controllo. Dati gli elementi:

Modello modello = new Modello(); //Usa Notificabile
Vista vista = new Vista(); //concretizza Notificabile
Controllo controllo = new Controllo();

l'applicazione deve funzionare con queste quattro (sole) relazioni:

modello.setNotificabile(vista);
vista.setControllo(controllo);
controllo.setModello(modello);

vale a dire Vista è un Notificabile, Vista usa Controllo, Modello usa Notificabile, Controllo usa Modello.

Nel caso specifico, l'ActionListener di cui parli è un pezzo di Controllo ed è connesso al pulsante posseduto dall'interfaccia nel momento in cui il Controllo è collegato alla Vista.

Le operazioni di gestione dei dati che comportino un riflesso sull'interfaccia (se premo X il pulsante Y si abilita) sono condotte dal controllo sul modello e riflesse sulla vista in quanto soggetto di notifiche da parte del modello sulle transizioni di stato.

Faccio un esempio del percorso logico che nell'architettura MVC porta da un evento di interazione subito da un elemento dell'interfaccia utente ad un riflesso su un altro elemento dell'interfaccia utente:

Dalla vista, premendo pulsanteX...
Codice:
//Vista.java
public void setControllo(Controllo c) {
    pulsanteX.addActionListener(c.getAscoltatorePerAzioneX());
    pulsanteY.addActionListener(c.getAscoltatorePerAzioneY());
    //eccetera...
}
si passa al controllo che gestisce la situazione...

Codice:
//Controllo
private void riflessoCollegatoAdAzioneX() {
     modello.setStatoY(false);
}

private ActionListener xListener = new ActionListener() {
    public void actionPerformed(ActionEvent e) {
       riflessoCollegatoAdAzioneX();
    }
};

public ActionListener getAscoltatorePerAzioneX() {
    return xListener;
}
provocando una mutazione del modello, comunicata a tutti i notificabili...

Codice:
//Modello.java
public void setStatoY(boolean valore) {
    valoreY = valore;
    for(Notificabile n : elencoNotificabili) {
        notificabile.gesticiNotifica(Notificabile.Y, true);
    }
}
e quindi alla vista stessa.

Codice:
//Vista.java
public void gestisciNotifica(int state, Object value) {
    if(state == Y_CHANGED) {
        buttonY.setEnabled((Boolean)value);
    }
}
In questo pseudo-codice ho considerato un ipotetico JButton come vista pura ma in realtà l'uso supposto sfrutta anche il modello di JButton (ButtonModel). Nel caso in cui la tua interfaccia deva interpretare in senso radicale la MVC allora il tuo Modello dovrà includere anche il (o i) ButtonModel e tale ButtonModel dovrà essere associato al JButton presentato nella vista all'atto della registrazione di quest'ultima come Notificabile per il modello.
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 24-09-2006, 14:54   #3
redcloud
Bannato
 
L'Avatar di redcloud
 
Iscritto dal: Feb 2003
Città: Anche Chuck Norris usa Debian e Gnome
Messaggi: 1270
Ottimo esempio ma non mi è chiara solo una cosa. Il modello dove prende la lista dei notificabili?
redcloud è offline   Rispondi citando il messaggio o parte di esso
Old 24-09-2006, 15:52   #4
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Sopra ho scritto "setNotificabile" ma semanticamente è più corretto rimpiazzarlo con "addNotificabile" perchè possono esserci più Viste che presentino i dati di un unico modello.

Più che un modello che "prende la lista di" parlerei di modello a cui "è rifilata una lista di" notificabili. In pseudo (molto pseudo) JavUML:

Codice:
interface Notifiable {}
Codice:
class Model {
    -Lista di Notificabili
    +aggiungiNotificabile(Notificabile n)
    +rimuoviNotificabile(Notifiacabile n)
}
Codice:
class Vista implements Notifiable {}
Codice:
//collega vista e modello
Modello m = new Modello();
Vista v = new Vista();
m.aggiungiNotificabile(v);//<- qui la vista inizia a presentare i dati
A onor del vero dovrei dire che il modello MVC non corrisponde esattamente a quanto da me riportato per la parte relativa al controllo. La versione originale prevede sì modello, notificabile e vista come riportati ma tratta in modo diverso il controllo che ha una doppia dipendenza:

controllo usa vista
controllo usa modello

anzichè la dipendenza singola (e contraria):

vista usa controllo

Nel senso originario, infatti, il controllo è la rappresentazione del dispositivo di input offerto all'utente per l'interazione con l'interfaccia grafica e deve avere a disposizione la mappa dei componenti presentati dalla vista per poter discriminare tra le diverse azioni possibili.

Pare una bizzarria ma è al modello originale che dobbiamo rifarci nel caso in cui, ad esempio, si voglia dotare una certa applicazione della possibilità di funzionare, alternativamente, con un controller a pulsanti piuttosto che con un mouse o un touch-screen.

Tuttavia, in ossequio all'architettura SMA, ogni componente Swing integra una meccanica predefinita di controllo. A quel punto la relazione Controllo->Vista non è più necessaria mentre è opportuno conservare l'indipendenza tra Vista e Modello delegando al Controllo la parte logica dell'interazione utente. Il che si traduce in una freccetta UML che fa una giravolta =).
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 24-09-2006, 16:15   #5
redcloud
Bannato
 
L'Avatar di redcloud
 
Iscritto dal: Feb 2003
Città: Anche Chuck Norris usa Debian e Gnome
Messaggi: 1270
Quindi in pratica torniamo al punto di partenza? L'MVC descritto da te non è quello puro, è la variante con call back. Nell'MVC puro è il controllo che si occupa di lavorare sul modello e di inoltrarli alla vista in quanto il modello non è intelligente (tanto da notificare la vista o per esempio lavorare sulla persistenza dei dati). Visto quindi che il modello è un bean, è il controllo che gestisce le comunicazioni. E' questo che hai detto nell'ultimo post?
redcloud è offline   Rispondi citando il messaggio o parte di esso
Old 24-09-2006, 18:36   #6
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
No. Il modello che definisco "originale" è quello che si chiama MVC ed è facilmente reperibile in qualsiasi manuale sulla piattaforma Smalltalk: il controllo usa la vista per ottenere le informazioni sulla distribuzione dei componenti. La versione che ho proposto è fondata sulla preesistenza del controllo nei componenti Swing che elimina la necessità di indagine del controllo sulla vista.
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
Old 24-09-2006, 21:07   #7
foxmolder5
Senior Member
 
Iscritto dal: Dec 2001
Messaggi: 2514
mi complimento e ti ringrazio per la spiegazione, ma la struttura che devo implementare è leggermente diversa.
io ho semplicemente una classe interfaccia, una classe controllo e poi nello strato inferiore vi è il "middleware" ( mysql con relativo strato di gestione del db).
ora il mio prob è:
se ho la classe interfaccia, dove dovrò inserire l'actionListener?
se lo inserisco nella classe interfaccia come faccio a far "ritornare" il controllo alla funzione controllo per l'esecuzione delle varie operazioni?
in quanto per ora la mia applicazione avrà l'istanza della classe di controllo che crea un'istanza della classe di interfaccia, viene eseguita l'interfaccia, però poi nn so come far tornare il comando alla classe di controllo.
foxmolder5 è offline   Rispondi citando il messaggio o parte di esso
Old 25-09-2006, 08:05   #8
redcloud
Bannato
 
L'Avatar di redcloud
 
Iscritto dal: Feb 2003
Città: Anche Chuck Norris usa Debian e Gnome
Messaggi: 1270
Swing ci facilita le cose, puoi semplicemente istanziare (all'interno della vista) le classi anonime actionListner per ciascun elemento grafico che attiva il relativo controllo. I controlli possono essere anche metodi statici (dipende comunque da cosa devono fare).
redcloud è offline   Rispondi citando il messaggio o parte di esso
Old 25-09-2006, 12:16   #9
PGI-Bis
Senior Member
 
L'Avatar di PGI-Bis
 
Iscritto dal: Nov 2004
Città: Tra Verona e Mantova
Messaggi: 4553
Be', visto che non parliamo più di MVC, l'ActionListener lo puoi mettere sia nel Controllo che nell'Interfaccia. In entrambi i casi o l'interfaccia possiede un riferimento al controllo o il controllo possiede un riferimento all'interfaccia. La cosa è necessaria per ogni caso di comunicazione primitiva tra due oggetti. Vediamo cosa cambia. Quindi avrai o una cosa tipo:

Codice:
public class InterfacciaUtente {
    private Controllo controllo;
    private JButton ilPulsante = new JButton(new AbstractAction("Salva") {
        public void actionPerformed(ActionEvent e) {
            if(controllo != null) {
                controllo.salva();
            }
        }
    });

    public void setControllo(Controllo c) {
        controllo = c;
    }
}
Codice:
public class Controllo {
    public void salva() {/*...*/}
}
o, per il caso Controllo->InterfacciaUtente

Codice:
public class Controllo {
    private InterfacciaUtente interfaccia;

    private ActionListener salvaListener = new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            salva();
        }
    };

    public void setInterfacciaUtente(InterfacciaUtente u) {
        interfaccia = u;
        AbstractButton salva = grabButton("salva");
        salva.removeActionListener(salvaListener);
        salva.addActionListener(salvaListener);
    }

    private AbstractButton grabButton(String key) {
        AbstractButton b= interfaccia.getButton(key);
        if(b== null) {
            throw new RuntimeException("Unexpected null value for key "+key);
        } else {
            return b;
        }
    }

    private void salva() {/*...*/}
}
Codice:
public class InterfacciaUtente {
    private Map<String, AbstractButton> buttonMap =
        new HashMap<String, AbstractButton>();

    private void init() {
        JButton salva = new JButton("Salva");
        buttonMap.put("salva", salva);
    }

    public AbstractButton getButton(String key) {
        return buttonMap.get(key);
    }
}
Nel primo caso InterfacciaUtente contiene i componenti UI e genera un rinvio, per quelli interagibili, agli opportuni comportamenti di Controllo. Controllo definisce le reazioni astrattamente associabili a dei componenti UI (e concretamente associate da InterfacciaUtente).

Nel secondo caso InterfacciaUtente contiene i componenti UI mentre Controllo definisce le reazioni e le associa all'atto della connessione con un InterfacciaUtente.

Tenendo conto che non siamo più nel campo MVC, alcune questioni pratiche mi farebbero preferire la seconda soluzione alla prima, in particolare quelle riguardanti l'introduzione di processi concorrenti che comportino un qualche effetto temporaneo sull'interfaccia utente. Non è detto tuttavia che tu abbia queste esigenze.
PGI-Bis è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Hyundai Ioniq 9: dopo due settimane di test non avremmo voluto restituirla Hyundai Ioniq 9: dopo due settimane di test non ...
LG UltraGear evo GM9: 27 pollici, 5K, Mini LED e Dual Mode LG UltraGear evo GM9: 27 pollici, 5K, Mini LED e...
Motorola edge 70 Fusion FIFA World Cup 26 Edition: un ottimo smartphone per i fan del calcio Motorola edge 70 Fusion FIFA World Cup 26 Editio...
Renault 5 elettrica al giudizio definitivo: solo stupore iniziale o premi meritati? Renault 5 elettrica al giudizio definitivo: solo...
HONOR CHOICE Projector Air Pro: piccolo, portatile e con Netflix HONOR CHOICE Projector Air Pro: piccolo, portati...
Microsoft ammette l'errore e risolve: ag...
Amazfit Active 3 Premium a 139€: smartwa...
Il razzo cinese Long March 7A esplode 85...
Beelink SER7 a 495€: mini PC con Ryzen 7...
Nvidia e Wall Street, 500 miliardi per l...
Cuffie top in offerta su Amazon: le Bose...
Alienware 16 con RTX 5070 a 1.899€: un m...
iPhone 17 è pronto a infrangere un recor...
iOS 27 beta 5: Apple prepara il contrass...
Candy RapidÓ PRO a 329€: lavatrice smart...
Zuckerberg promette a ognuno un agente I...
Pixel 11 Pro XL finisce su Geekbench con...
YouTube raddoppia la soglia per monetizz...
Componenti PC in offerta su Amazon: sche...
Windows 11 e la trasparenza personalizza...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 11:38.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Served by www3v