Question

I have a draggable JPanel that is added into a JFrame with the NetBeans IDE JFrame Form editor. When I run the program and drag the card somewhere other than the original position and resize the JFrame, the JPanel is returned to its original position.

Before (When program first run):

original position

Moved Card:

Moved Card

Resized Window:

Resized Window

I'm at a loss to understand why this happens and how to prevent it.

My Frame:

package cards;

import cards.cards.*;
/**
 *
 * @author Nicki
 */
public class ImgTest extends javax.swing.JFrame {

    /**
     * Creates new form ImgTest
     */
    public ImgTest() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        card2 = new cards.cards.Card();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Imgtest");
        setMinimumSize(new java.awt.Dimension(250, 250));
        setPreferredSize(new java.awt.Dimension(250, 250));

        javax.swing.GroupLayout card2Layout = new javax.swing.GroupLayout(card2);
        card2.setLayout(card2Layout);
        card2Layout.setHorizontalGroup(
            card2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 71, Short.MAX_VALUE)
        );
        card2Layout.setVerticalGroup(
            card2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 96, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(21, 21, 21)
                .addComponent(card2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(158, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(21, 21, 21)
                .addComponent(card2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(133, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]){
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(ImgTest.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(ImgTest.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(ImgTest.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(ImgTest.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ImgTest().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private cards.cards.Card card2;
    // End of variables declaration                   
}

My card panel:

package cards.cards;

import cards.images.CardImageProvider;
import java.awt.Canvas;
import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JPanel;

/**
 *
 * @author Nicki
 */
public class Card extends JPanel {

    private Image cardImg;
    private Cards card;
    private volatile int draggedAtX, draggedAtY;


    public Card(Cards c) {
        this.setSize(71, 96);
        card = c;
        cardImg = CardImageProvider.getCardImage(c);
        addMouseListener(new MouseAdapter(){

            public void mousePressed(MouseEvent e){
                draggedAtX = e.getX();
                draggedAtY = e.getY();
            }
        });

        addMouseMotionListener(new MouseMotionAdapter(){
            public void mouseDragged(MouseEvent e){
                setLocation(e.getX() - draggedAtX + getLocation().x,
                        e.getY() - draggedAtY + getLocation().y);
                repaint();
            }
        });
        this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    }

    public Card(){
        this(Unknown.UNKNOWN);
    }

    @Override
    public void paintComponent(Graphics g) {
        this.setSize(71, 96);
        g.drawImage(cardImg, 0, 0, this);
    }

    public void setCard(Cards c) {
        card = c;
        cardImg = CardImageProvider.getCardImage(c);
        repaint();
    }

    public Cards getCard() {
        return card;
    }


}

I would like to know how to prevent the card moving back to its first position. Thanks in advance.

Was it helpful?

Solution

By defaults an IDE will use a layout manager to position components on the frame.

When you drag the panel you are manually setting the location of the panel and overriding the location determined by the layout manager.

However, when you resize the frame the layout manager code is again executed and the panel is set back to its original position.

You need to change your code so that the parent panel of the panel you drag uses a "null layout". However, when you do this you are now responsible for setting the size and location of the panel.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top