Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Plaud NotePin S, il registratore IA si fa indossabile (ma è facile da perdere)
Plaud NotePin S, il registratore IA si fa indossabile (ma è facile da perdere)
Quattro modi di indossarlo, stessa app del Plaud Note Pro e integrazione con il desktop. Il registratore IA da indossare di Plaud eccelle in mobilità, ma resta vincolato all'abbonamento ed è facile da perdere
Redmi Watch 6 in prova: lo smartwatch con ampio display da 2000 nit a meno di 100 euro
Redmi Watch 6 in prova: lo smartwatch con ampio display da 2000 nit a meno di 100 euro
Xiaomi ha portato Redmi Watch 6 anche sul mercato italiano, puntando su un display AMOLED da 2,07 pollici con picco di luminosità a 2000 nit, frame in alluminio da 9,9mm e un'autonomia dichiarata di 12 giorni. Lo smartwatch gira su HyperOS 3 e integra GPS, Bluetooth 5.4 e oltre 150 sport mode. Il tutto a meno di 100 euro
Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ADV, ma con molti più pulsanti
Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ADV, ma con molti più pulsanti
Con 22 tasti, il pulsante 5D, lo Shift Mode e il sensore PixArt 3395 da 26.000 DPI, il nuovo mouse wireless di Mad Catz si rivolge in modo preciso ai giocatori di MMO e RPG. Ma chi conosce già il R.A.T. 8+ ADV si accorgerà subito di quanto i due prodotti condividano, e di dove invece divergono
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


Plaud NotePin S, il registratore IA si fa indossabile (ma è facile da perdere) Plaud NotePin S, il registratore IA si fa indoss...
Redmi Watch 6 in prova: lo smartwatch con ampio display da 2000 nit a meno di 100 euro Redmi Watch 6 in prova: lo smartwatch con ampio ...
Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ADV, ma con molti più pulsanti Mad Catz M.M.O. 7+: lo stesso DNA del R.A.T. 8+ ...
Radeon RX 9070 GRE, AMD la porta in tutto il mondo | Recensione Gigabyte Gaming OC Radeon RX 9070 GRE, AMD la porta in tutto il mon...
Reolink OMVI 3i WiFi: videosorveglianza più intelligente e facile da usare Reolink OMVI 3i WiFi: videosorveglianza pi&ugrav...
Samsung Galaxy S27 Pro: sarà lui ...
Così Google ha ottimizzato Chrome...
Xiaomi non cambia idea: il display poste...
LG presenta in Italia le gamme TV Micro ...
Sette anni dopo l'annuncio, The Wolf Amo...
'Non avrete aumenti': la decisione shock...
TIM lancia il Pass Mondiali DAZN: 104 pa...
Tesla Roadster, promessa o miraggio? La ...
Mark Hamilton, la tavola periodica del m...
Hanger 13 annuncia Uomo d'Onore: espansi...
La battaglia delle HBM4 entra nel vivo: ...
Dopo 12 anni torna Alien: Isolation. Ecc...
ADATA Trusta ridurrà i costi di i...
SpaceX fornirà 110.000 GPU NVIDIA...
Hyundai IONIQ 6 N-Line, prova in antepri...
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: 14:29.


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