Non funziona perchè dentro traits ci sono memorizzati tutti i tratti che l'utente ha fatto, ed alcuni erano tratti di disegno ed altri tratti di cancellazione, quindi tu non puoi basarti sul valore di 'draw' in quell'istante e disegnare tutti i tratti dello stesso colore. Quello che serve è sapere per ogni singolo tratto se è un tratto di disegno o un tratto di cancellazione.
Dunque segui il mio consiglio di modificare la classe Trait includendo un ulteriore campo che identifica se si tratta di un tratto di disegno o di cancellazione, io farei cosi:
codice:
//Classe per rappresentare un tratto di disegno
class Trait{
//valore che identifica un tratto di disegno
public static int DRAW_TRAIT = 0;
//valore che identifica un trato di cancellazione
public static int DELETE_TRAIT = 1;
public int startXPoint = 0;
public int startYPoint = 0;
public int endXPoint = 0;
public int endYPoint = 0;
//campo che è settato al valore di DRAW_TRAIT o di
//DELETE_TRAIT per distinguere un tratto di disegno
//da un tratto di cancellazione
private int traitType;
public Trait(int x1, int y1, int x2, int y2, int type){
startXPoint = x1;
startYPoint = y1;
endXPoint = x2;
endYPoint = y2;
traitType = type;
}
//Restituisce il tipo del tratto
public int getType(){
return traitType;
}
}
Inoltre togli questa classe dall'interno della classe Painter e rendila una clase autonoma (se no non compila). Quindi, quando crei un tratto di diegno nel costruttore devi includere l'intero che rappresenta il tipo di tratto, quindi l'evento di disegno è gestito cosi:
codice:
public void mouseDragged(MouseEvent e) {
//aggiorna le coordinate
startXPoint = endXPoint;
startYPoint = endYPoint;
endXPoint = e.getX();
endYPoint = e.getY();
//Se draw == true aggiungo un tratto di disegno
if(draw)
traits.add(new Trait(startXPoint, startYPoint, endXPoint, endYPoint, Trait.DRAW_TRAIT));
//altrimenti aggiungo un tratto di cancellazione
else
traits.add(new Trait(startXPoint, startYPoint, endXPoint, endYPoint, Trait.DELETE_TRAIT));
//disegna
repaint();
}
A questo punto nel metodo paintComponent ti basta sapere qual è il tipo di tratto per disegnarlo di un colore o di un altro, e lo puoi sapere col metodo getType() della classe Trait. Quindi per ogni tratto è sufficiente vedere che tipo di tratto è e settare il colre opportunamente:
codice:
public void paintComponent(Graphics g) {
super.paintComponent(g);
//Il disegno va rieptuto sempre
Trait t = null;
//disegno tutti i tratti
for(int i = 0; i < traits.size(); i++){
t = (Trait)traits.get(i);
if(t.getType() == Trait.DRAW_TRAIT){
//colore di disegno
g.setColor(Color.GREEN);
}
else{
//colore di sfondo
g.setColor(getBackground());
}
g.drawLine(t.startXPoint, t.startYPoint, t.endXPoint, t.endYPoint);
}
}
Infine resta il problema di rendere la linea piu spessa. Il modo piu semplice che mi viene in mente è semplicemente quello di diegnare piu linee una accanto all'altra in modo da aumentare lo spessore. Ad esempio se devi disegnare la linea che va da (10, 10) a (100, 100), puoi far variare la coordinata x del punto iniziale e del punto finale in un range di 5 pixel centrato in 10 per il punto iniziale e in 100 per il punto finale, ovvero puoi disegnare le seguenti 5 linee:
1 - da (10 - 2, 10) a (100 - 2, 100)
2 - da (10 - 1, 10) a (100 - 1, 100)
3 - da (10, 10) a (100, 100) ///linea originale!
4 - da (10 + 1, 10) a (100 + 1, 100)
5 - da (10 + 2, 10) a (100 + 2, 100)
in pratica non disegni solo il tratto vero e proprio ma ne disegni altri 4, di cui 2 a sinistra di quello originario e due a destra, e otteni ciò semplicemente facendo variare la coordinata x delle linee da x - 2 a x + 2 e rieffettuando il disegno per ognuno dei 5 valori.
Qui di seguito ti riporto il metodo paintComponent cosi modificato; ora la linea di disegno è spessa 9 punti mentre quella di cancellazione è di 25 punti; il disegno di piu linee avviene semplicemente eseguendo un ciclo for che fa viariare la coordinata x:
codice:
public void paintComponent(Graphics g) {
super.paintComponent(g);
//Il disegno va rieptuto sempre
Trait t = null;
//variabile per mantenere la meta dello spessore
//della linea
int points = 4;
//disegno tutti i tratti
for(int i = 0; i < traits.size(); i++){
t = (Trait)traits.get(i);
if(t.getType() == Trait.DRAW_TRAIT){
g.setColor(Color.GREEN);
points = 4;
}
else{
g.setColor(getBackground());
points = 12;
}
//disegno 2 * points + 1 linee per ottenere lo spessore
for(int j = -points; j <= points; j++)
g.drawLine(t.startXPoint + j, t.startYPoint, t.endXPoint + j, t.endYPoint);
}
}
A questo punto la cancellazione e il disegno funzionano. Ora puoi sbizarrirti aggiungendo nuove funzionalità, come:
- poter decidere lo spessore delle lenee
- poter usare colori diversi.
Tieni presente che queste caratteristiche sono tutte cartteristiche intrinseche di un tratto; ogni volta che disegni lo stesso stratto devi ridisegnarlo sempre con lo stesso spessore e lo stesso colore che aveva scelto l'utente, il che ti fa capire che devi ampliare la classe Trait in modo che possa includere informazioni sullo spessore e sul colore.
Ti metto allego il codice modificato completo e funzionante,
buon lavoro,
codice:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.JFrame.*;
import java.util.*;
//Classe per rappresentare un tratto di disegno
class Trait{
//valore che identifica un tratto di disegno
public static int DRAW_TRAIT = 0;
//valore che identifica un trato di cancellazione
public static int DELETE_TRAIT = 1;
public int startXPoint = 0;
public int startYPoint = 0;
public int endXPoint = 0;
public int endYPoint = 0;
//campo che è settato al valore di DRAW_TRAIT o di
//DELETE_TRAIT per distinguere un tratto di disegno
//da un tratto di cancellazione
private int traitType;
public Trait(int x1, int y1, int x2, int y2, int type){
startXPoint = x1;
startYPoint = y1;
endXPoint = x2;
endYPoint = y2;
traitType = type;
}
public int getType(){
return traitType;
}
}
//classe per gestire i pulsanti
class ButtonBar extends JToolBar implements ActionListener{
private Painter painter;
private JButton draw;
private JButton delete;
private JButton deleteAll;
public ButtonBar(Painter painter){
this.painter = painter;
setRollover(true);
draw = new JButton("draw");
delete = new JButton("delete");
deleteAll = new JButton("deleteAll");
add(draw);
add(delete);
add(deleteAll);
draw.addActionListener(this);
delete.addActionListener(this);
deleteAll.addActionListener(this);
}
public void actionPerformed(ActionEvent evt){
Object source = evt.getSource();
if(source == draw){
painter.draw();
}
if(source == delete){
painter.delete();
}
if(source == deleteAll){
painter.deleteAll();
}
}
}
class Painter extends JPanel {
private int startXPoint = 0; // coordinata x di partenza
private int endXPoint = 0; // coordinata x di arrivo
private int startYPoint = 0; // coordinata y di partenza
private int endYPoint = 0; // coordinata y di
//vale true se disegno, false se cancello
boolean draw = true;
//vettore che mantiene la lista dei tratti di disegno
private Vector traits;
// Costruttore della classe principale
public Painter() {
super();
MouseListener ml = new mListener();
addMouseListener(ml);
MouseMotionListener mml = new mMotionListener();
addMouseMotionListener(mml);
traits = new Vector();
}
//ascoltatore del moto del mouse
class mMotionListener implements MouseMotionListener {
public void mouseDragged(MouseEvent e) {
//aggiorna le coordinate
startXPoint = endXPoint;
startYPoint = endYPoint;
endXPoint = e.getX();
endYPoint = e.getY();
//Se draw == true aggiungo un tratto di disegno
if(draw)
traits.add(new Trait(startXPoint, startYPoint, endXPoint, endYPoint, Trait.DRAW_TRAIT));
//altrimenti aggiungo un tratto di cancellazione
else
traits.add(new Trait(startXPoint, startYPoint, endXPoint, endYPoint, Trait.DELETE_TRAIT));
//disegna
repaint();
}
public void mouseMoved(MouseEvent e) {
// aggiorna le coordinate
startXPoint = endXPoint;
startYPoint = endYPoint;
endXPoint = e.getX();
endYPoint = e.getY();
//traits.add(new Trait(startXPoint, startYPoint, endXPoint, endYPoint));
}
}
// ascoltatore dei pulsanti del mouse
class mListener implements MouseListener {
// i seguenti metodi sono richiesti dalla
// interfaccia MouseListener anche se non
// vengono utilizzati
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
// pulsante premuto
public void mousePressed(MouseEvent e) {
}
// pulsante rilasciato
public void mouseReleased(MouseEvent e) {
}
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
//Il disegno va rieptuto sempre
Trait t = null;
//variabile per mantenere la meta dello spessore
//della linea
int points = 4;
//disegno tutti i tratti
for(int i = 0; i < traits.size(); i++){
t = (Trait)traits.get(i);
if(t.getType() == Trait.DRAW_TRAIT){
g.setColor(Color.GREEN);
points = 4;
}
else{
g.setColor(getBackground());
points = 12;
}
for(int j = -points; j <= points; j++)
g.drawLine(t.startXPoint + j, t.startYPoint, t.endXPoint + j, t.endYPoint);
}
}
//Cancella tutti i tratti
public void deleteAll(){
traits = new Vector();
repaint();
}
//passa alla modalita di cancellazione
public void delete(){
draw = false;
}
//passa alla modalita di disegno
public void draw(){
draw = true;
}
public static void main(String argv[]) {
Painter p = new Painter();
JFrame f = new JFrame("Mia Prova Lavagna");
f.setSize(500, 400);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
JButton pulsante = new JButton("Cancella");
f.getContentPane().add(p, BorderLayout.CENTER);
f.getContentPane().add(new ButtonBar(p), BorderLayout.NORTH);
f.setVisible(true);
}
}