<

Il Drag end Drop

 

 

 

Oggetto: Riuscire a spostare degli oggetti con il mouse

 

 

Contenuti:

1

JLabel mouse events for Drag and Drop

2

 

3  
4  

 

Esempi:

1

 

2  
3  
4  

 

Procediamo con un esempio molto semplice:

Una icona (bottoncino) viene spostata cliccandoci sopra e dragando con il mouse

Per comprendere il meccanismo della creazione di eventi personalizzati vedi qui.

 

L'eseguibile

Classe: MyDrag

 1 package dragevent;
 2 
 3 import java.awt.Color;
 4 import java.awt.Dimension;
 5 import javax.swing.*;
 6 
 7 public class MyDrag extends JFrame {
 8       
 9     public MyDrag() {        
10         setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
11         getContentPane().setLayout(null);                     
12         setPreferredSize(new Dimension(600,200));
13         setLayout(null);
14         setLocationRelativeTo(null);
15         getContentPane().setBackground(Color.yellow);
16  
17         MyDrg mydr = new MyDrg("/image/drag03.png");       
18         mydr.setLocation(0, 50);             
19         add(mydr);
20 
21         pack();
22         setVisible(true);
23     }    
24 
25     public static void main(String args[]) {             
26         java.awt.EventQueue.invokeLater(new Runnable() {
27             public void run() {
28                 new MyDrag(); 
29             }
30         });
31     }          
32 }

 

Si limita a istanziare la classe MyDrag quella che ha il controllo totale sulla visualizzazione sia del pomello che della traccia di scorrimento e dei relativi eventi. Si occupa di posizionarla e di aggiungerla alla finestra righe 16-18.

 

La classe DragEvent

Classe: DragEvent

 1 package dragevent;
 2 
 3 import java.util.EventListener;
 4 import java.util.EventObject;
 5 
 6 // Evento
 7 class DragEvent extends EventObject{
 8     private int px;
 9     
10     public DragEvent(MyIcon source,int px){
11         super(source);
12         this.px=px;
13     }
14 
15     public int getMpos(){
16         return(px);   
17     }
18 }
19 //Interfaccia
20 interface MyDragListener extends EventListener{
21     public void posChanged(DragEvent event);   
22 }

 

Qui si definisce l'oggetto evento DragEvent. Oltre al riferimento al source sempre presente ha un secondo argomento con il quale riceverà l'attuale posizione x del mouse. Questi due parametri gli verranno passati nella classe MyIcon quando si implementerà il metodo fire. Il metodo getMpos() consentirà all'ascoltatore di leggere il valore della posizione del mouse.

 

L'ascoltatore

Nome della Classe:

 1 package dragevent;
 2     
 3 import javax.swing.JComponent;
 4 
 5 public class MyDrg extends JComponent{  
 6     private String po;
 7     private int pH,pW,dW,dH;
 8     private MyIcon myc;
 9     private Traks tdx;
10  
11     public MyDrg(String a){
12         po=a; 
13         //Trak di scorrimento
14         tdx = new Traks();        
15         dW=tdx.getWidth();
16         dH=tdx.getHeight();
17                
18         //Pomello
19         myc = new MyIcon(po);
20         pW=myc.getWidth();
21         pH=myc.getHeight();
22         
23         //Ascoltatore  - classe anonima        
24         myc.addDragListener(new MyDragListener() {
25             public void posChanged(DragEvent ev) {                                               
26                     tdx.setTrakW(ev.getMpos());
27             }         
28         });
29                    
30         tdx.setLocation(0,(pH-dH)/2 );
31         this.setSize(600, pH);
32         this.add(myc);                                  
33         this.add(tdx);                                     
34     }        
35 }

 

 

 

Questa classe assembla i due componenti il pomello e la traccia a scorrimento e si occupa di implementare un ascoltatore che catturerà gli eventi riguardanti lo spostamento del mouse inviati.Come si vede alla riga 26 tramite il metodo getMpos dell'oggetto eventDrag preleva la coordinata x del mouse e l'invia alla traccia scorrevole, metodo setTrakW che la userà per estendere o contrarre la traccia.

 

Il source MyIcon

  3 import java.awt.Dimension;
  4 import java.awt.Graphics;
  5 import java.awt.Graphics2D;
  6 import java.awt.Point;
  7 import java.awt.Shape;
  8 import java.awt.event.MouseAdapter;
  9 import java.awt.event.MouseEvent;
 10 import java.awt.event.MouseMotionAdapter;
 11 import java.awt.geom.Ellipse2D;
 12 import java.net.URL;
 13 import javax.swing.ImageIcon;
 14 import javax.swing.JLabel;
 15 import javax.swing.event.EventListenerList;
 16 
 17 public class MyIcon extends JLabel {
 18     
 19     private Point labelPt;    
 20     private Point mousePt;
 21     private ImageIcon pon;
 22     private int wp,hp;
 23     private String aa;
 24     private Shape shape = null; 
 25     private EventListenerList listeners;
 26     private int v;
 27     
 28     public MyIcon(String a) {
 29         aa=a;
 30         pon = createImageIcon(aa);
 31         wp=pon.getIconWidth();
 32         hp=pon.getIconHeight();
 33         this.setSize(600, hp);
 34         
 35         listeners = new EventListenerList();
 36         this.setPreferredSize(new Dimension(600, hp) );
 37         
 38         labelPt=new Point(0, 0);
 39         
 40         this.addMouseListener(new MouseAdapter() {
 41             @Override
 42             public void mousePressed(MouseEvent e) {
 43                 mousePt = e.getPoint();
 44                 repaint();
 45             }
 46         });
 47         this.addMouseMotionListener(new MouseMotionAdapter() {
 48             @Override
 49             public void mouseDragged(MouseEvent e) {
 50                 int dx = e.getX() - mousePt.x;
 51                 labelPt.setLocation(labelPt.x + dx, 0);
 52                 mousePt = e.getPoint();
 53                 firePosChangedEvent();
 54                 repaint();               
 55             }
 56         });
 57     }
 58     
 59     public void setVal(int v){
 60         this.v=v;
 61     }
 62 
 63     @Override
 64     public void paintComponent(Graphics g) {
 65         super.paintComponent(g);
 66         Graphics2D g2d =(Graphics2D)g;               
 67         shape=new Ellipse2D.Float(labelPt.x ,0 ,wp,hp);         
 68         pon.paintIcon(this, g2d,labelPt.x ,0);
 69     }
 70     
 71     @Override
 72     public boolean contains(int x, int y) {
 73         return shape.contains(x,y);
 74     }
 75     
 76     private ImageIcon createImageIcon(String path) {
 77          URL imgURL = getClass().getResource(path);
 78          if (imgURL != null) {
 79              return new ImageIcon(imgURL);
 80          } else {
 81              System.err.println("Non è possibile trovare il file: " + path);
 82            return null;
 83         }
 84      }
 85     
 86      private void firePosChangedEvent(){
 87             DragEvent event = new DragEvent(this,mousePt.x);
 88             Object[] listenersArray = listeners.getListenerList();
 89             for(int i = listenersArray.length - 2; i >= 0; i -= 2){
 90              if(listenersArray[i] == MyDragListener.class){
 91              ((MyDragListener)listenersArray[i+1]).posChanged(event);
 92             }
 93          }
 94     }
 95      
 96     public void addDragListener(MyDragListener listener){
 97         listeners.add(MyDragListener.class, listener);
 98     }
 99 }

 

Per quanto riguarda il disegno del pomello ed il caricamento dell'immagine relativa vedi qui.

Farei invece notare:

  1. L'import della classe che ci fornirà la lista dgli ascoltatori (riga15)
  2. Nel costruttore della classe l'istanza di una lista di ascoltatori (riga 25 e 35)
  3. Il metodo fire, uno per ciascun tipo di evento che si vuole lanciare (riga 86)
  4. Un metodo che ci permetterà di aggiungere alla lista un ascltatore (riga96)
  5. Non ho implementato il metodo per togliere l'ascotatore dalla lista qui non è necessario
  6. Un lancio di evento nel punto (riga 53)

 

La classe Traks - La traccia scorrevole

 3 import javax.swing.JLabel;
 4 
 5 public class Traks extends JLabel{
 6     private int tkw;
 7     
 8     public Traks(){
 9         setBackground(java.awt.Color.red);
10         setOpaque(true); 
11         setSize(40,30);
12     }
13     
14     public void setTrakW(int kw){
15         tkw=kw;
16         setSize(tkw,30);
17     }
18 }

 

Questa classe si commenta da sola.

Livelli