Προς το περιεχόμενο

Java Drag n' Drop με χρήση JLayeredPane...


loverman210

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπέρα σε όλους!

 

Είμαι αρχάριος σχετικά στη java και ψάχνοντας στο internet βρήκα ένα κομμάτι κώδικα ο οποίος ουσιαστικά δείχνει πως μπορεί να γίνει drag n' drop αντικειμένων σε περιβάλλον swing. Καθότι ο κώδικας είναι σχετικά απλός σας τον παραθέτω ολόκληρο μαζί με την απορία μου...

 

>import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class ChessBoard extends JFrame implements MouseListener, MouseMotionListener
{
   JLayeredPane layeredPane;
   JPanel chessBoard;
   JLabel chessPiece;
   int xAdjustment;
   int yAdjustment;


   public ChessBoard()
   {
       Dimension boardSize = new Dimension(600, 600);

       //  Use a Layered Pane for this this application

       layeredPane = new JLayeredPane();
       getContentPane().add(layeredPane);
       layeredPane.setPreferredSize( boardSize );
       layeredPane.addMouseListener( this );
       layeredPane.addMouseMotionListener( this );

       //  Add a chess board to the Layered Pane

       chessBoard = new JPanel();
       layeredPane.add(chessBoard, JLayeredPane.DEFAULT_LAYER);
       chessBoard.setLayout( new GridLayout(8, 8) );
       chessBoard.setPreferredSize( boardSize );
       chessBoard.setBounds(0, 0, boardSize.width, boardSize.height);

       for (int i = 0; i < 64; i++)
       {
           JPanel square = new JPanel( new BorderLayout() );  //very important for the location of the penguin picture
           chessBoard.add( square );														//inside the little-panels-containers

           int row = (i / 8) % 2;
           System.out.println(row);
           if (row == 0)          //here "row" will be changing periodically  from 0 to 0,875 and 1 to 1,875. We care only about
           											 //the first digit meaning 0 or 1 because the type of the variable "row" is int
               square.setBackground( i % 2 == 0 ? Color.red : Color.white );
           else
               square.setBackground( i % 2 == 0 ? Color.white : Color.red );
       }

       // Add a few pieces to the board

       JLabel piece = new JLabel( new ImageIcon("pigkouinos.gif") );
       JPanel panel = (JPanel)chessBoard.getComponent( 18 );    //we cast the return of the component as a panel
       panel.add( piece );
       piece = new JLabel( new ImageIcon("pigkouinos2.gif") );
       panel = (JPanel)chessBoard.getComponent( 15 );
       panel.add( piece );
   }

   /*
   **  Add the selected chess piece to the dragging layer so it can be moved
   */
   public void mousePressed(MouseEvent e)
   {
       chessPiece = null;									//if we skip the null value, then the whole block of code will also be skipped
       																		//and @ mouseDragged event, the "chessPiece" won't be defined
       Component c =  chessBoard.findComponentAt(e.getX(), e.getY());


       if (c instanceof JPanel) return;

       Point parentLocation = c.getParent().getLocation();
       xAdjustment = e.getX() - parentLocation.x;						//we actually neutralize the distance to which
       yAdjustment = e.getY() - parentLocation.y;            //we have come so far over the surface of the label
       chessPiece = (JLabel)c;
       chessPiece.setLocation(e.getX() - xAdjustment, e.getY() - yAdjustment);
       chessPiece.setSize(chessPiece.getWidth(), chessPiece.getHeight());			//optional
       layeredPane.add(chessPiece, JLayeredPane.DRAG_LAYER);

   }

   /*
   **  Move the chess piece around
   */
   public void mouseDragged(MouseEvent me)
   {
       if (chessPiece == null) return;
       
       chessPiece.setLocation(me.getX() - xAdjustment, me.getY() - yAdjustment);
}

   /*
   **  Drop the chess piece back onto the chess board
   */
   public void mouseReleased(MouseEvent e)
   {
       if (chessPiece == null) return;

       chessPiece.setVisible(false);
       Component c =  chessBoard.findComponentAt(e.getX(), e.getY());  //because we don't know where the user will stop dragging

       if (c instanceof JLabel)
       {
           Container parent = c.getParent();
           parent.remove(0);     						//This if avoids the overlapping
           parent.add( chessPiece );
       }
       else
       {
           Container parent = (Container)c;	//And this is the normal one
           parent.add( chessPiece );
       }

       chessPiece.setVisible(true);
   }

   public void mouseClicked(MouseEvent e) {}
   public void mouseMoved(MouseEvent e) {}
   public void mouseEntered(MouseEvent e) {}
   public void mouseExited(MouseEvent e) {}

   public static void main(String[] args)
   {
       JFrame frame = new ChessBoard();
       frame.setDefaultCloseOperation( DISPOSE_ON_CLOSE );
frame.pack();
       frame.setResizable(true);
       frame.setLocationRelativeTo( null );
       frame.setVisible(true);
    }
}

 

Λοιπόν, το θέμα εδώ είναι τα mouseEvents ουσιαστικά! Κοιτώντας προσεκτικά το πως λειτουργεί η όλη app, μπορώ να πώ οτι "το'χω" εκτός απο ένα σημέιο:

 

->Αν στο mousePressed Event, διαγράψω την πρώτη γραμμή, δηλ το "chessPiece = null", έτσι ώστε κάθε φορά που κάνω κλικ στο mouse, εκείνο να μην κάνει πλέον null τις τιμές του chessPiece, το ερώτημα είναι, γιατί αν εκείνη τη στιγμή κλικάρω κάπου αλλού στη σκακιέρα, την ώρα που θα κάνω DRAG το mouse, η φωτογραφία μου θα εξαφανίζεται και δε θα ακολουθεί το mouse??

 

P.S Η απορία είναι πολύ συγκεκριμένη και για να καταλάβετε καλύτερα τι εννοώ, κάντε απλά copy-paste τον κώδικα σε έναν editor της επιλογής σας και αντικαταστήστε τα ονόματα των δικών .gif, με τις δικές σας pic...

 

Χίλια ευχαριστώ για τον χρόνο σας!

  • 2 εβδομάδες αργότερα...
Δημοσ.

Δυστυχώς βρήκα μόνο αυτό το οποίο δε λέει και πολλά...

 

http://www.insomnia.gr/forum/showthread.php?t=327195&highlight=drag+n+drop

 

Το drag n drop καταλαβαίνω τι κάνει ...το πρόβλημα είναι αν στο συγκεκριμένο κώδικα που δίνω...πειράξουμε μία μικρή γραμμούλα όπως παραπάνω τι συμβαίνει...

  • 2 εβδομάδες αργότερα...
Δημοσ.

Ερώτηση Νο2:

 

---Αν κρατήσουμε τον κώδικα ακριβώς όπως τον παραθέτω, και απλά προσπαθήσουμε να προσθέσουμε το chessPiece στο DRAG_LAYER κάτω απο το mouseDragged και όχι κάτω απο το mousePressed,

γιατί δεν θα έχει αποτέλεσμα?---

 

Επιπλέον παρατήρησα ότι όχι μόνο δε δουλεύει, αλλά επιπλέον, κάθε φορά που κάνουμε dragging το mouse, εάν θέσουμε setResizable(true) και κάνουμε resize το JFrame, θα το δούμε να κρύβεται πίσω απο το chessBoard το οποίο βρίσκεται ήδη στο default layer...

Απάντηση με παράθεση

Αρχειοθετημένο

Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.

  • Δημιουργία νέου...