Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    Includere un classe esterna che gestisce gli eventi...?

    Salve. Ho questo file principale:

    codice:
    import java.awt.*;
    import javax.swing.*;
    
    public class Biliardo extends JPanel
    {
    	int raggio;
    	int millis;
    	boolean Dx;
    	Point Coords;
    	Timer timer;
    	
    	public Biliardo(int rg, int ms)
    	{
    		raggio = rg;
    		millis = ms;
    		Dx = true;
    		Coords = new Point();
    		timer = new Timer (millis, new TimerHandler());
    		timer.start();
    	}
    	
    	public void paintComponent (Graphics g)
    	{
    		super.paintComponent(g);
    		
    		Dimension d = getSize();
    		Coords.y = d.height;
    		
    		g.setColor (Color.GREEN);
    		g.fillOval (Coords.x, Coords.y / 2 - raggio, raggio * 2, raggio * 2);
    	}
    
    	public static void main (String[] args)
    	{
    		JFrame frame = new JFrame ("Biliardo");
    		frame.setSize (200, 160);
    		frame.setLocationRelativeTo (null);
    		frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    		
    		Biliardo panel = new Biliardo(50, 50);
    		panel.setBackground (Color.WHITE);	
    		frame.add (panel);
    		
    		frame.setVisible (true);		
    	}
    }
    Quando faccio timer = new Timer (millis, new TimeHandler()), inizializzo il timer e come secondo parametro gli passo la classe che gestisce gli eventi, ma mi da errore...

    la classe TimerHandler è questa:

    codice:
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;
    import java.awt.Dimension;
    
    public class TimerHandler extends Biliardo implements ActionListener
    {
    	public void actionPerformed (ActionEvent e)
    	{
    		Dimension d = getSize();
    		if (Dx)
    		{
    			if (Coords.x >= d.width - 2 * raggio)
    			{
    				Dx = false;
    			}
    			else
    			{
    				Coords.x++;
    			}
    		}
    		else
    		{
    			if (Coords.x <= 0)
    			{
    				Dx = true;
    			}
    			else
    			{
    				Coords.x--;
    			}
    		}
    		
    		repaint();
    	}
    }
    Cosa c'è che sbaglio?

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: Includere un classe esterna che gestisce gli eventi...?

    Originariamente inviato da Dreamer89
    Cosa c'è che sbaglio?
    Non ha alcun senso che tu faccia:

    public class TimerHandler extends Biliardo implements ActionListener

    L'errore tecnicamente te lo dà per una questione legata ai costruttori. Nella superclasse Biliardo hai definito esplicitamente un costruttore con argomenti. E questo vuol dire che il costruttore di default (senza argomenti) non c'è. Nella sottoclasse TimerHandler non hai definito alcun costruttore e quindi il costruttore di default stavolta c'è eccome. Solo che il costruttore di default fa una invocazione super() (senza argomenti) ma ... nella superclasse non c'è un costruttore senza argomenti!!!

    A parte questo ... così facendo (estendere Biliardo) pensavi forse di poter accedere ai componenti, campi ecc... di Biliardo?? Tecnicamente è possibile ma .... quando fai new TimerHandler() crei una nuova istanza di TimerHandler che ha i "suoi" campi raggio, millis, Coords ecc... che non centrano nulla con gli stessi campi ma nell'oggetto Biliardo che crei con:

    Biliardo panel = new Biliardo(50, 50);

    Insomma ... sono due cose diverse e infatti la estensione che hai fatto non ha senso.

    La gestione degli eventi è una cosa da fare in modo molto "intimo" con la classe che definisce e gestisce la interfaccia utente. Quindi in genere si usano delle inner-class, non classi esterne.

    Se volessi usare classi esterne, dovresti rendere accessibile all'esterno tutto ciò che serve agli handler. E questa non è una buona pratica.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2007
    Messaggi
    35
    Non hai definito i costruttori di default nelle classi Biliardo e TimerHandler

  4. #4
    Però mi pare che estendendo TimerHandler a Biliardo, posso richiamare repaint e quindi posso interagire con l'altra classe. Mi piacerebbe separare gli eventi in un altro file in modo da spezzettare il lavoro e rendere tutto più chiaro...

  5. #5
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Dreamer89
    Però mi pare che estendendo TimerHandler a Biliardo, posso richiamare repaint e quindi posso interagire con l'altra classe.
    No ripeto che sarebbero oggetti diversi!!!

    Quando fai:

    Biliardo panel = new Biliardo(50, 50);

    Crei un oggetto di tipo Biliardo, che hai i suoi campi raggio, millis, ecc... ed è il pannello che a tutti gli effetti inserisci nella interfaccia utente.

    Quando fai:

    new Timer (millis, new TimerHandler());

    crei un altro oggetto, di tipo TimerHandler che essendo una estensione di Biliardo, possiede (eredita...) pure lui i campi raggio, millis ecc... ma è tutto un altro oggetto!!!! E non centra nulla con l'altro oggetto Biliardo, che è quello nella interfaccia utente e su cui devi agire!!!

    Oltretutto quale costruttore di Biliardo chiameresti?? Non certo quello che hai messo con i due argomenti int ... anche perché creeresti un altro TimerHandler .... e così via ....

    Quella estensione non ha senso.

    Originariamente inviato da Dreamer89
    Mi piacerebbe separare gli eventi in un altro file in modo da spezzettare il lavoro e rendere tutto più chiaro...
    Allora usa le inner-class.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  6. #6
    Originariamente inviato da andbin
    No ripeto che sarebbero oggetti diversi!!!

    Quando fai:

    Biliardo panel = new Biliardo(50, 50);

    Crei un oggetto di tipo Biliardo, che hai i suoi campi raggio, millis, ecc... ed è il pannello che a tutti gli effetti inserisci nella interfaccia utente.

    Quando fai:

    new Timer (millis, new TimerHandler());

    crei un altro oggetto, di tipo TimerHandler che essendo una estensione di Biliardo, possiede (eredita...) pure lui i campi raggio, millis ecc... ma è tutto un altro oggetto!!!! E non centra nulla con l'altro oggetto Biliardo, che è quello nella interfaccia utente e su cui devi agire!!!

    Oltretutto quale costruttore di Biliardo chiameresti?? Non certo quello che hai messo con i due argomenti int ... anche perché creeresti un altro TimerHandler .... e così via ....

    Quella estensione non ha senso.

    Allora usa le inner-class.
    Le inner-class? Ma come collego un file ai suoi eventi che si trovano in un'altra classe esterna?

  7. #7
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da Dreamer89
    Ma come collego un file ai suoi eventi che si trovano in un'altra classe esterna?
    Se proprio vuoi gestire gli eventi con classi esterne, tecnicamente è fattibile. Ma la classe esterna dovrebbe ottenere, tipicamente tramite costruttore, un reference alla classe da gestire.

    Esempio (ometto gli import):

    codice:
    public class MyFrame extends JFrame
    {
        JButton button;     // accesso almeno di "default", se non addirittura public!!
    ....
    
        button.addActionListener (new MyHandler (this));
    ...
    }
    
    - - - - altro sorgente - - - -
    
    public class MyHandler implements ActionListener
    {
        private MyFrame frame;
    
        public MyHandler (MyFrame frame)
        {
            this.frame = frame; 
        }
    
        public void actionPerformed (ActionEvent e)
        {
            frame.button.setText ("blabla");  // esempio
        }
    }
    a) È brutto.
    b) È lungo e noioso ... devi sempre usare quel 'frame' per usare/invocare qualcosa.
    c) Viola palesemente una delle principali regole della OOP, ovvero l'incapsulamento.


    EDIT: l'esempio che ho fatto è decisamente il peggiore per quanto riguarda il punto c). Se dovessi impostare da MyHandler il testo del pulsante potrei decidere, ad esempio, di tenere privato il 'button' e mettere in MyFrame un metodo pubblico per fare ciò ma in ogni caso sarebbe codice in più e comunque da valutare, se vale la pena o no, in base a cosa si deve fare.
    Indipendentemente da questo, MyHandler deve avere comunque un reference a MyFrame.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  8. #8
    Grazie mille ^^

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 © 2025 vBulletin Solutions, Inc. All rights reserved.