Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it
    Registrato dal
    Apr 2008
    Messaggi
    52

    problema esercizio con eventi del mouse

    ciao, ho dei problemi con un esercizio che riguarda gli eventi del mouse e spero in un vostro aiuto ^^ allora prima di tutto guardate queste due classi.

    la classe che estende una JComponent:

    codice:
    package grafica;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.geom.Ellipse2D;
    
    import javax.swing.JComponent;
    
    public class CerchioMouseComponent extends JComponent {
    	
    	public CerchioMouseComponent()
    	{
    		circle = new Ellipse2D.Double(0, 0, 100, 100);
    	}
    	
    	public void paintComponent(Graphics g)
    	{
    		Graphics2D g2 = (Graphics2D)g;
    		g2.draw(circle);
    	}
    	
    	public void moveTo(double x, double y, double raggio)
    	{
    		circle.setFrame(x, y, raggio, raggio);
    		repaint();
    	}
    	
    	private Ellipse2D.Double circle;
    
    }
    e questa invece è la classe con il main (dove è implementato anche il listener):

    codice:
    package grafica;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    public class CerchioMouseViewer {
    
    	public static void main(String[] args) {
    		
    		JFrame frame = new JFrame();
    		JLabel label = new JLabel("Raggio");
    		final JTextField field = new JTextField(5);
    		field.setText("" + 200);
    		JPanel panel = new JPanel();
    		panel.add(label);
    		panel.add(field);
    		frame.add(panel);
    		JFrame frame1 = new JFrame();
    		final CerchioMouseComponent component = new CerchioMouseComponent();
    		
    		class MousePressListener implements MouseListener
    		{
    			public void mousePressed(MouseEvent event)
    			{
    				double raggio = Double.parseDouble(field.getText()) / 2;
    				double x = event.getX() - raggio / 2;
    				double y = event.getY() - raggio / 2;
    				component.moveTo(x, y, raggio);
    			}
    			
    			public void mouseReleased(MouseEvent event) {}
    			public void mouseClicked(MouseEvent event) {}
    			public void mouseEntered(MouseEvent event) {}
    			public void mouseExited(MouseEvent event) {}
    		}
    		
    		MouseListener listener = new MousePressListener();
    		component.addMouseListener(listener);
    		frame1.add(component);
    	        frame.setSize(150, 68);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame1.setSize(300, 400);
    		frame1.setLocation(200, 0);
    		frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setVisible(true);
    		frame1.setVisible(true);
    
    	}
    
    }
    in pratica ci sono due frame, un un piccolo frame dove viene settata la dimensione del raggio e in un secondo frame più grande c'è disegnato un cerchio iniziale, appena si clicca con il mouse su un punto di questo secondo frame, il cerchio viene spostato (con il centro nel punto cliccato) e viene anche ridimensionato il raggio (nel caso si cambia il valore).

    ora vorrei apportare delle modifiche che però non riesco a fare:

    1) vorrei che il cerchio iniziale non fosse visibile e appena si clicca la prima volta con il mouse sul frame compare (naturalmente con il centro nel punto cliccato).

    2) nel mio caso ogni volta il cerchio viene spostato, ma vorrei fare in modo che ad ogni click sul frame il cerchio precedente rimane nella sua posizione e ne compare uno nuovo nel punto cliccato, come posso fare?

    spero possiate darmi una mano, grazie ^^

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

    Re: problema esercizio con eventi del mouse

    Originariamente inviato da auron567
    2) nel mio caso ogni volta il cerchio viene spostato, ma vorrei fare in modo che ad ogni click sul frame il cerchio precedente rimane nella sua posizione e ne compare uno nuovo nel punto cliccato, come posso fare?
    Si può fare ma .... ti faccio notare alcune cose, che devi cambiare.

    Al momento stai ancora usando il layout manager predefinito del content pane del frame, ovvero BorderLayout. Con un semplice add(component) aggiungi il componente nella parte CENTER del BorderLayout. Tale parte occupa tutto lo spazio disponibile. Ecco perché il MouseListener funziona bene. Perché il tuo componente è espanso per occupare tutto lo spazio del JFrame.
    Nota che solo 1 componente per volta è visibile nella parte CENTER! Se anche ne aggiungessi altri con quel add() .... ne vedresti solo 1 (l'ultimo aggiunto)!

    No, se vuoi avere più figure devi cambiare le cose. Hai 2 soluzioni: a) Ogni cerchio è disegnato con un componente a parte, posizionato e dimensionato esplicitamente della giusta dimensione (e devi togliere il layout manager dal content pane) oppure b) Definisci 1 solo componente che ha una lista di figure che disegni in blocco nel paintComponent().

    In ogni caso devi cambiare un po' le cose. Non so se ti è chiaro .... chiedi se hai dubbi. Tra i miei Java Examples trovi esempi in cui c'è 1 componente unico che disegna più figure.
    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
    Apr 2008
    Messaggi
    52
    forse teoricamente ho capito più o meno, ma a livello di pratica non tanto... se per esempio voglio disegnare i vari componenti nel paintComponent, il problema è che io non so il numero preciso di questi componenti (visto che se ne dovrebbe creare uno nuovo ad ogni click del mouse), quindi come faccio? in pratica non ho capito bene come aggiungere un componente tramite un evento... mi potresti se hai tempo mostrare a livello di codice qualcosa di pratico?

    ah, e per la prima domanda?

    grazie ancora e scusa per il disturbo... ^^ ora dò un'occhiata anche ai tuoi esempi...

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da auron567
    se per esempio voglio disegnare i vari componenti nel paintComponent, il problema è che io non so il numero preciso di questi componenti
    Nel tuo componente che disegna tutto quanto, a te basta tenere una "collezione". Ammettiamo che ti servano solo oggetti Ellipse2D.Double. Bene, fai una collezione ArrayList<Ellipse2D.Double>. Ogni volta che devi aggiungere un ellisse, lo istanzi (e inizializzi con dei valori), lo aggiungi alla collezione e chiedi il repaint(). Nel paintComponent() si ridisegnerà tutto, con anche la nuova figura.

    Originariamente inviato da auron567
    ora dò un'occhiata anche ai tuoi esempi...
    Lì ci troverai esempi che usano la tecnica che ho detto sopra.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    Apr 2008
    Messaggi
    52
    Originariamente inviato da andbin
    Ogni volta che devi aggiungere un ellisse, lo istanzi (e inizializzi con dei valori), lo aggiungi alla collezione e chiedi il repaint().
    di preciso questa operazione dove la devo compiere? in quale metodo?

    per il primo problema nessuna soluzione?

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da auron567
    di preciso questa operazione dove la devo compiere? in quale metodo?
    Codice parziale (giusto solo per farti capire) di una classe PannelloEllissi che estende JPanel.

    codice:
    public class PannelloEllissi extends JPanel {
        private ArrayList<Ellipse2D.Double> listaEllissi;
    
        public PannelloEllissi() {
            listaEllissi = new ArrayList<Ellipse2D.Double>();
        }
    
        public void aggiungiEllisse(Ellipse2D.Double ell) {
            // Aggiungi l'ellisse nella collezione
            // Chiedi il repaint()
        }
    
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
    
            Graphics2D g2d = (Graphics2D) g;
    
            // Fai una iterazione sulla collezione
            // Per ogni ellisse lo disegni sul Graphics2D
        }
    }
    Da un'altra parte (es. dove gestisci il JFrame) registri un MouseListener sulla istanza del tuo PannelloEllissi. Nel mousePressed() fai/calcoli quello che vuoi, istanzi un Ellipse2D.Double e lo passi semplicemente al aggiungiEllisse()

    Originariamente inviato da auron567
    per il primo problema nessuna soluzione?
    Ma non ho ben capito .... vuoi un cerchio iniziale che sia invisibile all'inizio e diventi visibile al primo click. Ma poi vuoi che ne compaia uno ad ogni click. Insomma vuoi proprio così? Entrambe le cose?
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it
    Registrato dal
    Apr 2008
    Messaggi
    52
    no, il primo problema lo considero a se stante (cioè senza considerare il secondo problema). praticamente voglio che quando avvio il programma il cerchio iniziale non sia visibile, e lo diventi dopo il primo click, naturalmente nella posizione cliccata. poi ad ogni click si sposta, ma questa già mi funziona come dovrebbe.... io avevo provato a mettere component.setVisible(false) quando istanzio la componente nel main in modo che non sia visibile, poi nel metodo dell'evento del mouse dopo averla spostata la mettevo true, ma non so perchè non mi compare niente...

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da auron567
    no, il primo problema lo considero a se stante (cioè senza considerare il secondo problema). praticamente voglio che quando avvio il programma il cerchio iniziale non sia visibile, e lo diventi dopo il primo click, naturalmente nella posizione cliccata.
    Beh ma allora non è questione di crearlo invisibile e poi renderlo visibile ..... semplicemente al click lo istanzi nuovo (con la posizione del click) e lo aggiungi come ho spiegato sopra.

    Originariamente inviato da auron567
    poi ad ogni click si sposta
    Ma prima dicevi che vuoi farne comparire uno nuovo ad ogni click.

    Allora scusa, ragiona ... tutto si riduce semplicemente così: "ad ogni click aggiungi un nuovo ellisse"!! Non devi "spostare" nulla e rendere "visibile" nulla.

    E allora lo scheletro parziale di codice che ho postato sopra è quello che ti serve: poter aggiungere e disegnare un numero "arbitrario" di ellissi.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Utente di HTML.it
    Registrato dal
    Apr 2008
    Messaggi
    52
    si, vero hai ragione ^^ ora mi metto all'opera e vedo se riesco a realizzare questo programma usando lo schizzo di codice che mi hai postato... ti faccio sapere se va tutto liscio (naturalmente ti faccio sapere anche in caso contrario )

    grazie ancora...

  10. #10
    Utente di HTML.it
    Registrato dal
    Apr 2008
    Messaggi
    52
    scusate il doppio post, ma andbin volevo dirti che sono riuscito a far funzionare il programma perfettamente grazie al tuo consiglio, grazie mille ^^

    visto che sono qua, volevo postare un altro problemino che ho con un esercizio simile (anche se questa volta non c'è di mezzo il mouse). allora inizio postando il codice.

    questa è la classe componente (realizzata grazie al tuo aiuto andbin ^^):

    codice:
    package grafica;
    import java.util.ArrayList;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Rectangle;
    import javax.swing.JPanel;
    
    public class RettangoliCasualiComponent extends JPanel {
    	
    	public RettangoliCasualiComponent()
    	{
    		listaRettangoli = new ArrayList<Rectangle>();
    	}
    	
    	public void aggiungiRettangolo(Rectangle rettangolo)
    	{
    		listaRettangoli.add(rettangolo);
    		repaint();
    	}
    	
    	public void paintComponent(Graphics g)
    	{
    		Graphics2D g2 = (Graphics2D)g;
    		for(int i=0; i<listaRettangoli.size(); i++)
    		{
    			Rectangle rettangolo = listaRettangoli.get(i);
    			g2.draw(rettangolo);
    		}
    	}
    	
    	private ArrayList<Rectangle> listaRettangoli;
    
    }
    e questa è la classe del main con l'implementazione del listener:

    codice:
    package grafica;
    import java.awt.Rectangle;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Random;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    public class RettangoliCasualiViewer {
    
    	public static void main(String[] args) {
    		
    		JFrame frame = new JFrame();
    		JLabel label = new JLabel("Numero di Rettangoli:");
    		final JTextField field = new JTextField(4);
    		field.setText("" + 5);
    		JButton button = new JButton("Disegna");
    		JPanel panel = new JPanel();
    		panel.add(label);
    		panel.add(field);
    		panel.add(button);
    		frame.add(panel);
    		JFrame frame1 = new JFrame();
    		final RettangoliCasualiComponent component = new RettangoliCasualiComponent();
    		
    		class RettangoliCasualiListener implements ActionListener
    		{
    			public void actionPerformed(ActionEvent event)
    			{
    				Random generator = new Random();
    				int n = Integer.parseInt(field.getText());
    				for(int i=0; i<n; i++)
    				{
                                            int x = generator.nextInt(FRAME_WIDTH);
    					int y = generator.nextInt(FRAME_HEIGHT);
    					Rectangle rettangolo = new Rectangle(x, y, LARGHEZZA, ALTEZZA);
    					component.aggiungiRettangolo(rettangolo);
    				}
    			}
    		}
    		
    		RettangoliCasualiListener listener = new RettangoliCasualiListener();
    		button.addActionListener(listener);
    		frame1.add(component);
    		frame.setSize(300, 75);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame1.setSize(FRAME_WIDTH, FRAME_HEIGHT);
    		frame1.setLocation(350, 0);
    		frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setVisible(true);
    		frame1.setVisible(true);
    
    	}
    	
    	private static final int FRAME_WIDTH = 300;
    	private static final int FRAME_HEIGHT = 400;
    	private static final int LARGHEZZA = 20;
    	private static final int ALTEZZA = 30;
    
    }
    il programma è semplice: come il precedente, c'è un primo frame dove si setta il numero di rettangoli da stampare e un pulsate "Disegna", quando si preme il pulsante sul secondo frame compaiono questi rettangoli in posizioni casuali. il secondo frame ha dimensioni 330 * 400 ed il problema è che alcuni rettangoli compaiono fuori dal frame, altri invece compaiono a metà. vorrei non far succedere questa cosa ed ho anche capito cosa modificare, ma non come...

    in pratica le due istruzioni da modificare sono queste:

    int x = generator.nextInt(FRAME_WIDTH);
    int y = generator.nextInt(FRAME_HEIGHT);

    però non riesco a trovare la "formula" giusta in modo che tutti i rettangoli compaiono precisi all'interno del frame (al massimo toccano i bordi).

    andbin mi serve ancora il tuo aiuto ^^ scusami ancora per il disturbo e grazie

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.