Sviluppo esonero del 17.04.09 per entrambe i gruppi

Per il primo gruppo si richiedevano i seguenti punti:

Scrivere un programma java che disegna un frame di dimensioni 300×200
Associare al pannello contenuto nel frame gli ascoltatori per mouse e tastiera,
usando le classi adapter, affinchè vengano intercettati i seguenti eventi:

  • Doppio click: disegnare un rettangolo rosso di dimensioni 50×50 con il centro in
    corrispondenza del punto in cui è avvenuto il click
  • Mouse Pressed:se il mouse intercetta uno dei rettangoli, colorare il rettangolo
    di blu
  • Pressione del tasto a: se un rettangolo è colorato di blu (ovvero è stato
    selezionato) ingrandire il rettangolo di 10 pixel
  • Pressione del tasto z: se un rettangolo è colorato di blu (ovvero è stato
    selezionato) ridurre il rettangolo di 10 pixel

Facoltativo:
Colorare i rettangoli successivi con un valore di alpha decrescente

Ed ecco come ho sviluppato il codice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.geom.*;
 
public class EsoneroGruppo1
{
	public static void main(String[] argv)
	{
		JFrame f = new JFrame("Esonero - Gruppo 1");
		f.getContentPane().add(new BasePane1());
		f.setSize(500, 500);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setVisible(true);
	}
}
 
class BasePane1 extends JPanel
{
	private ArrayList figure = null;
	private int selected = -1;
 
	public BasePane1()
	{
		super();
		figure = new ArrayList();
		eventHandler();
		setFocusable(true);
		requestFocus();
	}
 
	public void eventHandler()
	{
		addMouseListener(new MouseAdapter()
		{
			public void mousePressed(MouseEvent e)
			{
				if (e.getClickCount() > 1)
					figure.add(new Quadrato(e.getPoint()));
				else
				for (int i=0; i<figure.size(); i++)
					if ( ((Quadrato)figure.get(i)).contains(e.getPoint()) )
							selected = i;
			}
		});
 
		addKeyListener(new KeyAdapter()
		{
			public void keyPressed(KeyEvent e)
			{
				if (selected != -1)
				{
					switch (e.getKeyCode())
					{
						case KeyEvent.VK_A:
							((Quadrato)figure.get(selected)).editSize(true);
							break;
						case KeyEvent.VK_Z:
							((Quadrato)figure.get(selected)).editSize(false);
							break;
					}
				}
			}
		});
 
		new javax.swing.Timer(50, new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				repaint();
			}
		}).start();
	}
 
	public void paint(Graphics _g)
	{
		Graphics2D g = (Graphics2D)_g;
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		super.paintComponent(g);
 
		for (int i=0; i<figure.size(); i++)
		{
			g.setColor(new Color(255, 0, 0, 100+100/(i+1)));
			if (i == selected)
				g.setColor(new Color(0, 255, 255, 100+100/(i+1)));
			g.fill( ((Quadrato)figure.get(i)) );
		}
	}
}
 
class Quadrato extends Rectangle2D.Double
{
	public static final int DIM = 25;
	private Point p = null;
	private int size = DIM;
 
	public Quadrato(Point p)
	{
		super();
		this.p = p;
		muovi(p);
	}
 
	public void muovi(Point p)
	{
		setFrame(p.x-size, p.y-size, size*2, size*2);
	}
 
	public void editSize(boolean inc)
	{
		size = (inc)? size + 5 : size - 5;
		muovi(p);
	}
}

Per il secondo gruppo, invece:

Scrivere un programma java che disegna un frame di dimensioni 300×200
Associare al pannello contenuto nel frame gli ascoltatori per mouse e tastiera,
usando le classi adapter, affinchè vengano intercettati i seguenti eventi:

  • Pressione del tasto e: disegnare un ellisse di dimensioni 50×50 e colore rosso
    al centro del pannello
  • Pressione del tasto r: disegnare un rettangolo di dimensioni 50×50 e colore
    rosso al centro del pannello
  • Doppio click: se il mouse intercetta uno dei rettangoli, rimuovere il rettangolo
  • Mouse Drag: se il puntatore del mouse intercetta uno dei rettangoli, trascinare il
    rettangolo fino al rilascio del pulsante, visualizzando il trascinamento

Facoltativo:
Colorare i rettangoli successivi con un valore di alpha decrescente

Ed ecco come ho sviluppato anche questo codice:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
import javax.swing.*;
import java.util.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.geom.*;
 
/*
 * Classe contenente il metodo MAIN
 */
public class EsoneroGruppo2
{
	/*
	 * Il metodo instanzia un JFrame all'interno del quale verrà posizionato
	 * il pannello con il quale si svolgeranno le azioni richieste
	 */
	public static void main(String[] argv)
	{
		JFrame f = new JFrame("Esonero - Gruppo 2");
 
		//Inerimento del pannello per java 1.4
		f.getContentPane().add(new BasePane2());
 
		f.setSize(500, 500);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setVisible(true);
	}
}
 
/*
 * Classe BasePane
 * Questa classe permette la gestione dell'array di figure (Quadrati e Cerchi)
 * mediante l'utilizzo degli ascoltatori sia del mouse che della tastiera.
 * Con la pressione del tasto 'e' si crea un nuovo cerchio mentre con il tasto 'r'
 * si crea un nuovo quadrato.
 * vengono posizionati di default al centro del pannello, aventi entrambe le figure
 * dimensioni 50x50 px.
 * Sono draggabili e al doppio click su una di esse avviene la cancellazione dall'array.
 */
class BasePane2 extends JPanel
{
	//Array d figure
	private ArrayList figure = null;
 
	//Selezione di una figura per il drag
	private int selection = -1;
 
	/*
	 * Il costruttore istanzia un nuovo arraylist
	 * richiama il metodo che gestisce gli eventi
	 * e imposta il pannello come "focusable" e ne richiama il focus
	 */
	public BasePane2()
	{
		super();
 
		figure = new ArrayList();
 
		eventHandler();
 
		setFocusable(true);
		requestFocus();
	}
 
	/*
	 * Metodo che gestisce gli ascoltatori degli eventi del mouse
	 * e della tastiera.
	 * Contiene anche un timer che ha il compito di svolgere un repaint ogni 50ms
	 */
	public void eventHandler()
	{
		addMouseListener(new MouseAdapter()
		{
			public void mousePressed(MouseEvent e)
			{
				//Se si clicca più di una volta
				if (e.getClickCount() > 1)
				{
					//si scorre l'array
					for (int i=0; i<figure.size(); i++)
						//se si è selezionata una figura con il mouse
						if ( ((Figura)(figure.get(i))).isSelected(e.getPoint()) )
							//la si rimuove dall'array
							figure.remove(i);
				}
				//altrimenti, se il click è singolo
				else
				{
					//si scorre l'array
					for (int i=0; i<figure.size(); i++)
						//per selezionare la figura sulla quale si trova il mouse
						if ( ((Figura)(figure.get(i))).isSelected(e.getPoint()) )
							//e se ne salva l'indice nella variabile "selection"
							selection = i;
				}
			}
			public void mouseReleased(MouseEvent e)
			{
				//quando viene rilasciato il mouse la variabile torna ad assumere il suo valore standard
				selection = -1;
			}
		});
 
		addMouseMotionListener(new MouseMotionAdapter()
		{
			public void mouseDragged(MouseEvent e)
			{
				//Se la variabile ha assunto valori diversi da quello standard
				if (selection != -1)
					//si sposta la figura associata all'indice dell'array indicato dalla variabile
					((Figura)(figure.get(selection))).muovi(e.getPoint());
			}
		});
 
		addKeyListener(new KeyAdapter()
		{
			public void keyPressed(KeyEvent e)
			{
				//creazione di figure differenti a seconda dei tasti premuti
				switch(e.getKeyCode())
				{
					case KeyEvent.VK_E:
						figure.add(new Figura( new Point(getWidth()/2, getHeight()/2), 'e' ));
						break;
					case KeyEvent.VK_R:
						figure.add(new Figura( new Point(getWidth()/2, getHeight()/2), 'r' ));
						break;
				}
			}
		});
 
		new javax.swing.Timer(50, new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				repaint();
			}
		}).start();
	}
 
	public void paint(Graphics _g)
	{
		Graphics2D g = (Graphics2D)_g;
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		super.paintComponent(g);
 
		for (int i=0; i<figure.size(); i++)
		{
			//impostazione del colore con trasparenza crescente
			g.setColor( new Color(255, 0, 0, 100+155/(i+1)) );
 
			//prelevamento del punto associato alla posizione della figura attuale
			Point p = ((Figura)(figure.get(i))).getLocation();
 
			//controllo del tipo di figura da disegnare
			if ( ((Figura)(figure.get(i))).getType() == 'e' )
				g.fill( new Ellipse2D.Double(p.x-Figura.DIM, p.y-Figura.DIM, Figura.DIM*2, Figura.DIM*2) );
			else if ( ((Figura)(figure.get(i))).getType() == 'r' )
				g.fill( new Rectangle2D.Double(p.x-Figura.DIM, p.y-Figura.DIM, Figura.DIM*2, Figura.DIM*2) );
		}		
	}
}
 
/*
 * Classe che definisce le caratteristiche di una figura
 * con campi relativi al punto centrale di posizionamento
 * e tipo di figura da disegnare
 */
class Figura
{
	//Dimensione della figura da disegnare
	public static final int DIM = 25;
 
	private Point p = null;
	private char type = '0';
 
	/*
	 * Il costruttore crea una nuova figura nel punto indicato
	 * del tipo indicato
	 */
	public Figura(Point p, char type)
	{
		this.p = p;
		this.type = type;
	}
 
	/*
	 * metodo che effettua un controllo per ferificare che il punto "p1"
	 * si trovi all'interno della figura disegnata
	 */
	public boolean isSelected(Point p1)
	{
		//Controllo di posizione per il quadrato
		if (type == 'r')
		{
			if ((p.x-DIM<p1.x && p.x+DIM>p1.x) && (p.y-DIM<p1.y && p.y+DIM>p1.y))
				return true;
		}
		//Controllo di posizione per il cerchio
		else if (type == 'e')
		{
			if ( Math.pow(p.x-p1.x, 2) + Math.pow(p.y-p1.y, 2) < Math.pow(DIM, 2) )
				return true;
		}
		return false;
	}
 
	/*
	 * metodo per lo spostamento della figura
	 */
	public void muovi(Point p)
	{
		this.p = p;
	}
 
	/*
	 * Metodo per il ritorno del tipo di figura
	 */
	public char getType()
	{
		return type;
	}
 
	/*
	 * metodo per il ritorno della posizione della figura
	 */
	public Point getLocation()
	{
		return p;
	}
}

NOTA
Ovviamente il codice è sviluppato secondo le mie idee e i miei metodi di ragionamento.
Non per forza avreste dovuto fare come ho fatto io. Le strade per arrivare ai risultati proposti possono essere parecchie. Quindi non disperate se le vostre soluzioni sono differenti da quelle che ho proposto io.

About the Author

Hello everyone! I'm Andrea Rastelli, a 23 year old programmer, designer, 3D animator and compositor. You may follow me on Twitter and Facebook