Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Mova Z70 Ultra Roller Complete: motore potente, rullo di lavaggio e l'IA a guidare
Mova Z70 Ultra Roller Complete: motore potente, rullo di lavaggio e l'IA a guidare
Mova Z70 Ultra Complete è un robot aspirapolvere che coniuga un'aspirazione potente e un lavaggio con rullo a logica di intelligenza artificiale che guida al meglio nella pulizia di casa: rulli e spazzole estensibili a pulire gli angoli e una base di ricarica che lava e ripristina il robot al emglio delle sue funzionalità dopo ogni azione di pulizia
Recensione Google Pixel 11: non ha l'HiLight dei Pro, ma è il Pixel più equilibrato di sempre
Recensione Google Pixel 11: non ha l'HiLight dei Pro, ma è il Pixel più equilibrato di sempre
Abbiamo provato Google Pixel 11, il più accessibile della nuova gamma: chip Tensor G6 condiviso con i modelli Pro, fotocamera 48 MP con Magic Capture e Stili Fotografici, display Actua da 3000 nit e batteria da 4985 mAh. Ecco come si comporta nell'uso quotidiano, e cosa cambia davvero rispetto a Pixel 11 Pro e Pro XL
Google Pixel 11 Pro XL: fotocamera al top, batteria indietro. Luci e ombre del nuovo flagship
Google Pixel 11 Pro XL: fotocamera al top, batteria indietro. Luci e ombre del nuovo flagship
Google Pixel 11 Pro XL debutta in Italia con il nuovo Tensor G6, lo Zoom Pro fino a 120x, il display Super Actua da 3600 nit e la new entry HiLight riservata ai modelli Pro: lo abbiamo provato in anteprima per diversi giorni prima del lancio commerciale, tra fotocamera generativa, ricarica ancora indietro rispetto ai rivali e un prezzo che parte da 1399 euro
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


Mova Z70 Ultra Roller Complete: motore potente, rullo di lavaggio e l'IA a guidare Mova Z70 Ultra Roller Complete: motore potente, ...
Recensione Google Pixel 11: non ha l'HiLight dei Pro, ma è il Pixel più equilibrato di sempre Recensione Google Pixel 11: non ha l'HiLight dei...
Google Pixel 11 Pro XL: fotocamera al top, batteria indietro. Luci e ombre del nuovo flagship Google Pixel 11 Pro XL: fotocamera al top, batte...
Non sai programmare? Ecco cosa si può fare con un LLM e una GeForce RTX 5070 Ti Non sai programmare? Ecco cosa si può far...
Recensione Samsung Galaxy Z Fold8 Ultra: il pieghevole più famoso diventa quasi perfetto Recensione Samsung Galaxy Z Fold8 Ultra: il pieg...
22 offerte Amazon da non perdere, dalla ...
Bose QuietComfort Earbuds a 129,95€: ANC...
L'unico con tante scorte, non fatevi sca...
Torna il super doppio sconto sulle e-bik...
Offerte Amazon componenti PC: RTX 5060 T...
Crucial Pro DDR5 da 32GB a 389,99€: perc...
Fable 5, il modello più potente d...
PC all-in-one Lenovo super elegante, per...
Lo Smart TV più venduto su Amazon...
Periferiche gaming in offerta su Amazon:...
L'IA non è una bolla, ma pu&ograv...
Il cinema in salotto: oggi TV Xiaomi QLE...
Passa a ho. Mobile, fino a fine agosto c...
Ai Giochi di Pechino i robot prendono fu...
Arianespace Ariane 6: lanciato il satell...
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:45.


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