MouseListener

di Anonimizzato21567 il
17 risposte
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

  • 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
  • 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
  • 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....
    }
  • 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.
  • 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.
  • 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.
  • 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 ...
  • Cioè il MouseListener lo devo inserire nella classe CellLabel?
  • JAVA2222 ha scritto:


    Cioè il MouseListener lo devo inserire nella classe CellLabel?
    No. O perlomeno, non è quello il punto!
  • Ma in che punto del codice dovrei fare il cast a CellLabel?
  • 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?
  • 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();
        // ....
    }
  • Usando tuoCellLabel.addMouseListener(unMouseListener); mi dà come errore : non static-method addMouseListener cannot be referenced from a static context.
  • 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