Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1

    Propagare azione o ActionEvent per custom component

    Ciao a tutti,

    ho uno scenario per cui chiedo consiglio, capito il quale mi si aprirà un mondo nuovo sicuramente; un attimo di pazienza che spiego il tutto

    Si supponga di avere 2 classi ed un applet, di cui:
    la prima classe è
    codice:
    public class SpecialList extends List{...}
    la quale è una lista da me personalizzata, mentre la seconda classe è
    codice:
    public class SpecialComponent extends Panel
    {
       Button[] vButton;
       ...
    }
    che è un pannello che gestisce dinamicamente una lista di bottoni in esso contenuti; ed infine un applet che utilizza queste due classi (o componenti)
    codice:
    public class MyApplet extends Applet
    {
       SpecialList sl;
       SpecialComponent sc;
       ...
    }
    Ora volendo fare in modo che delle azioni compiute su questi oggetti membro, scaturisca qualcosa nella classe MyApplet, cosa devo fare?

    "Improvvisando" ho visto che da MyApplet faccio
    codice:
    sl.addActionListener(this);
    in MyApplet esegue actionPerformed (ovviamente se debitamente implementato), e lo fa perché comunque SpecialList è una lista.
    Invece il codice
    codice:
    sc.addActionListener(this);
    non è possibile farlo, poiché il Panel non implementa questo metodo; se dichiaro il metodo addActionListener in SpecialComponent, in cui "collego" il listener (MyApplet) ad ogni bottone dell'array, esso riceve l'azione del click in actionPerformed, tuttavia come sorgente dell'evento risulta il singolo bottone interno e non il loro componente padre SpecialComponent.

    Mi rendo conto che la cosa è intrecciata, ma spero che almeno la questione sia chiara...

    Idee?
    "La mia vita finirà quando non vedrò più la gente ridere.... non necessariamente alle mie battute."

  2. #2
    Utente di HTML.it
    Registrato dal
    Apr 2007
    Messaggi
    157
    Se non vado errato, c'è il metodo getParent() o qualcosa di simile, che restituisce il componente in cui esso è contenuto. Cerca su google

  3. #3

    grazie, ma altra stranezza

    Originariamente inviato da alde90
    Se non vado errato, c'è il metodo getParent() o qualcosa di simile, che restituisce il componente in cui esso è contenuto. Cerca su google
    Magari mi aspettavo qualcosa ad eventi più raffinato, però così va più che bene, grazie davvero :-P
    Tuttavia la chiamata
    codice:
    public void actionPerformed(ActionEvent event)
    {
       getParent().actionPerformed(event);
    }
    all'interno di SpecialList funziona correttamente, mentre in SpecialComponent il compilatore lamenta un "cannot find symbol" all'altezza del punto referente. Eppure actionPerformed è definito in MyApplet (che appunto dovrebbe essere il parent)... non è che avete illuminazioni anche in merito a questo?
    "La mia vita finirà quando non vedrò più la gente ridere.... non necessariamente alle mie battute."

  4. #4
    Utente di HTML.it
    Registrato dal
    Apr 2007
    Messaggi
    157
    getParent() restituisce un JComponent, che di per sè non implementa il metodo actionPerformed. Devi castarlo prima, in questo modo
    codice:
    public void actionPerformed(ActionEvent event) {
        ((SpecialComponent) getParent()).actionPerformed(event);
     }
    Lancia un'eccezione se non riesce a castare, eventualmente puoi fare un controllo così

    codice:
    JComponent parent = getParent();
    if(parent instanceof SpecialComponent){
        ((SpecialComponent) parent).actionPerformed(event);
    }

  5. #5

    Dio ti benedica! :)

    Grazieee, scemo io!
    Però solo una cosa è da assettare, poi è esattamente quello che volevo fare!

    Nel codice che mi hai suggerito, non si può castare il getParent a SpecialComponent in quanto (e l'exception che ne consegue lo dice) getParent() torna un oggetto di tipo MyApplet (giustamente), infatti se scrivo
    codice:
    ((MyApplet) getparent()).actionPerformed(event);
    compila ed esegue tutto correttamente.

    La chicca finale che manca è quella di rendere la classe portabile e riutilizzabile (come Bjarne insegna :-P ), per fare ciò sarebbe bello poter eliminare quel cast hardcode a MyApplet.
    E' possibile quindi eliminare il cast a MyApplet e sostituirlo con un qualche modello, o riferimento di tipo al parent... o che so io? Qualcosa come
    codice:
    ((ParentType) getParent()).actionPerformed(event);
    "La mia vita finirà quando non vedrò più la gente ridere.... non necessariamente alle mie battute."

  6. #6
    Utente di HTML.it
    Registrato dal
    Apr 2007
    Messaggi
    157
    Non so se si possa fare, quello che ti ho suggerito è l'unico metodo che conosco, ma non credo che si possa fare, per il fatto che il compilatore di Java è molto rigido, e facendo così dovrebbe controllare i metodi a livello di runtime, e il compilatore (ovviamente) non è in grado di fare questo

  7. #7

    beh in effetti...

    Originariamente inviato da alde90
    Non so se si possa fare, quello che ti ho suggerito è l'unico metodo che conosco, ma non credo che si possa fare, per il fatto che il compilatore di Java è molto rigido, e facendo così dovrebbe controllare i metodi a livello di runtime, e il compilatore (ovviamente) non è in grado di fare questo
    Sì in effetti è più una cosa da linguaggio interpretato...
    Evidentemente non è questa la strada giusta per implementare una classe portabile...una specie di libreria.
    Mi viene da domandarmi allora come facciano le classi Java a fare quel che fanno, con la gestione di azioni ed eventi... per poi portare ovviamente lo stesso discorso in una mia classe: in fin dei conti neanche loro conoscono il nome della classe su cui andranno a lavorare... no?
    "La mia vita finirà quando non vedrò più la gente ridere.... non necessariamente alle mie battute."

  8. #8
    Utente di HTML.it
    Registrato dal
    Apr 2007
    Messaggi
    157
    Loro infatti usano delle interfacce, e tu devi implementare quelle per potere usare certi metodi. Infatti l'actionPerformed è definito dall'interfaccia ActionEvent. Per aggiungere un ascoltatore di eventi, devi creare una classe che implementa l'interfaccia ActionEvent (e relativi metodi). Così facendo riesci ad aggirare il problema del compilatore

  9. #9

    Ricevuto!

    Bene, vorrà dire che mi devo studiare per bene il funzionamento delle interfacce ed il "come" implementarle per le mie classi...

    Grazie infinite per la tua pazienza!
    "La mia vita finirà quando non vedrò più la gente ridere.... non necessariamente alle mie battute."

  10. #10
    Utente di HTML.it
    Registrato dal
    Apr 2007
    Messaggi
    157
    Figurati

    Più che studiare questo, devi studiare il concetto più generale degli oggetti. Le interfacce sono state definite in Java per permettere la multi-ereditarietà, senza problemi per quel che riguarda il conflitto di codice (esempio si estendono due classi, tutte e due con il metodo doSomething(). Se fossero già implementate, quale scegliere?? Con le interfacce si risolve il problema, perchè il metodo viene definito nella classe stessa)

    In breve, quando implementi un'interfaccia fai sapere al compilatore che, oltre ai metodi base di Object, hai anche i metodi definiti in quell'interfaccia. Così facendo puoi sfruttare il concetto di ereditarietà (se A è l'interfaccia, e B è la classe che la implementa, B è di tipo B (ovviamente) ma anche di tipo A. Per il compilatore, vuol dire che questo metodo è implementato, quindi non genera errore).

    Scusa se non sono molto chiaro, ma sono mezzo influenzato e non riesco a spiegarmi molto chiaramente

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.