MouseListener

di il
17 risposte

MouseListener

Salve, sto scrivendo un gioco in java.
La schermata di gioco è divisa in quadrati ( che sono JLabel), e quando si clicca su una di esse ho bisogno di sapere quale è stata cliccata. Mi sembra di aver capito che non posso utilizzare ActionListener con le JLabel, quindi ho provato con un MouseListener ma non capisco come "applicarlo" ad ogni singola JLabel; il mouselistener dev'essere unico e non so come posso riconoscere quale JLabel è stata cliccata.

17 Risposte

  • Re: MouseListener

    Vorrei specificare che ho provato a creare un Array di rettangoli e tramite un ciclo for ad ognuno di essi ho impostato le coordinate delle corrispondenti JLabel con il comando:
    rect[i][y].setLocation(bottoni[i][y].getX(),bottoni[i][y].getY());
    (rect è l'array di rettangoli e bottoni quello delle JLabel.
    Su questa riga però Java mi dà l'errore
    java.lang.NullPointerException
  • Re: MouseListener

    Ho risolto l'errore NullPointerException, ma comunque, assegnata a ogni rettangolo l'origine della corrispondente JLabel, nel momento del click non viene mai trovato un rettangolo che contenga il punto cliccato
  • Re: MouseListener

    JAVA2222 ha scritto:


    Mi sembra di aver capito che non posso utilizzare ActionListener con le JLabel
    No infatti. JLabel è un componente "passivo" il cui scopo è solo generalmente quello di mostrare qualcosa (testo e/o icona). Ma non genera "azioni" di qualche tipo.

    JAVA2222 ha scritto:


    quindi ho provato con un MouseListener
    Sì MouseListener è lecito per tutti i componenti, essendo una gestione a "basso" livello del mouse.

    JAVA2222 ha scritto:


    ma non capisco come "applicarlo" ad ogni singola JLabel; il mouselistener dev'essere unico e non so come posso riconoscere quale JLabel è stata cliccata.
    La implementazione di MouseListener (nel senso di quale classe lo implementa) è di certo unica. Poi bisogna vedere se hai 1 istanza del listener che usi per TUTTI i JLabel oppure invece se vuoi/puoi avere una istanza del listener distinta da assegnare a ciascun JLabel.

    Se la istanza del listener è una sola, ovviamente NON potrà mantenere al suo interno informazioni che permettono di determinare quale JLabel, come riga/colonna, è quello interessato. Se avessi istanze distinte del listener, invece sì è possibile.

    In sostanza, per risolvere la cosa bene e in modo "object oriented":

    1) Incapsuli riga/colonna nella label, questo però presuppone di estendere JLabel:
    public class CellLabel extends JLabel {
        private int riga;
        private int colonna;
    
        // costruttore, getter, ecc...
    }
    In questo caso puoi avere una sola istanza del listener. Il "source" dell'evento sai a priori che saranno oggetti CellLabel, quindi fai un cast e puoi usare i suoi dati aggiuntivi.

    oppure

    2) Incapsuli riga/colonna nel listener e questo presuppone che poi avrai una istanza del listener DISTINTA per ciascuna label:
    public class CellLabelMouseListener implements MouseListener {
        private int riga;
        private int colonna;
    
        // costruttore, mouseClicked, ecc....
    }
  • Re: MouseListener

    Se io volessi usare il primo metodo, e implementare JLabel, dovrei quindi creare un array non più di JLabel ma di CellLabel ( dal suo esempio), vero?
    Come si estende la classe JLabel in modo che io possa usare questo metodo?
    E poi, per capire quale JLabel è stata cliccata potrò usare il metodo e.getComponent?(con e l'evento del mouse)
    Grazie in anticipo per la risposta.
  • Re: MouseListener

    JAVA2222 ha scritto:


    dovrei quindi creare un array non più di JLabel ma di CellLabel ( dal suo esempio), vero?
    Sì, naturalmente. Un array di tipo CellLabel[][] e ovviamente istanziare N oggetti CellLabel.

    JAVA2222 ha scritto:


    Come si estende la classe JLabel in modo che io possa usare questo metodo?
    Ma l'ho scritto prima. Basta aggiungere costruttore, metodi getter e quant'altro sia utile.

    JAVA2222 ha scritto:


    E poi, per capire quale JLabel è stata cliccata potrò usare il metodo e.getComponent?(con e l'evento del mouse)
    Generalmente si usa il "source" ( e.getSource() ) ma per certi oggetti di evento che derivano da ComponentEvent c'è anche getComponent(). La differenza è che getSource() è molto più generalizzato (e ritorna Object) mentre getComponent() è "fissato" sul fatto che il source deve essere un Component.

    Comunque se usi oggetti CellLabel su cui registri il listener, tu saprai per certo che il source è un CellLabel, quindi fai il cast a CellLabel e potrai usare i suoi dati aggiuntivi.
  • Re: MouseListener

    Ho usato il primo metodo ma quando clicco su una CellLabel (la classe che appunto estende le JLabel), il metodo e.getSource() mi ritorna JFrame mentre io vorrei sapere quale CellLabel è stata cliccata.
  • Re: MouseListener

    JAVA2222 ha scritto:


    Ho usato il primo metodo ma quando clicco su una CellLabel (la classe che appunto estende le JLabel), il metodo e.getSource() mi ritorna JFrame mentre io vorrei sapere quale CellLabel è stata cliccata.
    Se hai registrato un MouseListener sul CellLabel e su questo ci sono eventi del mouse, il source dell'evento È il CellLabel.
    Avrai sbagliato qualcosa nel codice ...
  • Re: MouseListener

    Cioè il MouseListener lo devo inserire nella classe CellLabel?
  • Re: MouseListener

    JAVA2222 ha scritto:


    Cioè il MouseListener lo devo inserire nella classe CellLabel?
    No. O perlomeno, non è quello il punto!
  • Re: MouseListener

    Ma in che punto del codice dovrei fare il cast a CellLabel?
  • Re: MouseListener

    Si creo di di aver capito che devo farlo nel mouselistener, ma appunto mi dice che è impossibile convertire frame in celllabel. Devo togliere il JFrame?
  • Re: MouseListener

    JAVA2222 ha scritto:


    Ma in che punto del codice dovrei fare il cast a CellLabel?
    tuoCellLabel.addMouseListener(unMouseListener);
    
    // ...
    
    public void mouseClicked(MouseEvent e) {          // nella impl. di MouseListener ovviamente
        CellLabel cellLabel = (CellLabel) e.getSource();
        // ....
    }
  • Re: MouseListener

    Usando tuoCellLabel.addMouseListener(unMouseListener); mi dà come errore : non static-method addMouseListener cannot be referenced from a static context.
  • Re: MouseListener

    Praticamente ho creato una classe Listener a parte che implementa mouselistener e nella classe del main ho usato il metodo CellLabel.addMouseListener(unMouseListener); ma mi dà quell'errore.
    Cosa c'è di sbagliato?
Devi accedere o registrarti per scrivere nel forum
17 risposte