0

So I found this code here, it works, it just causes quite a lot of juddering - (the faster you drag the more the image shakes) - in the image when it's dragged. OP said it wasn't optimized and since it's a dead post I thought I'd see if anyone here could help! I've also tried the code from stack, but I couldn't get it to do anything. If anyone has any suggestions for this code, or a better solution I'd love to hear it!

OF note, my Jpanel that needs to be dragged around (paintComponent drawn object) is inside a scrollpane!

   //initial reference point  
   private Point mouseLocation;  
   public void mousePressed(MouseEvent evt){  
      mouseLocation = evt.getPoint();  
   }  
   public void mouseDragged(MouseEvent evt){  
      //current mouse location  
      Point newLoc = evt.getPoint();  
      //deltas  
      int deltaX = newLoc.x-mouseLocation.x;  
      int deltaY = newLoc.y-mouseLocation.y;  
      p.setLocation(p.getX()+deltaX,p.getY()+deltaY);  
      //move the reference point to the current location  
      this.mouseLocation = newLoc;  
   }  

Here is a sample program that shows the juddering!

Community
  • 1
  • 1
Darkstarone
  • 4,590
  • 8
  • 37
  • 74
  • You can use interpolation or high pass filter..but can you put the whole code so I could test the jittering on my computer? – Shivam Jan 30 '13 at 21:29
  • It's 6 classes and 700 lines of code! However I did put the paintcomponent up yesterday [here](http://stackoverflow.com/questions/14574770/jscrollpane-not-scrolling-past-a-set-size) and in the original post another poster said it caused the same problems as myself, so I don't think it's program specific. I.e if you build something similar the jittering should occur. I shall work on creating a small test program to showcase it. – Darkstarone Jan 30 '13 at 21:39

1 Answers1

3

So I found this code here, it works, it just causes quite a lot of juddering

Then I would say that it does not work. And if you read the post carefuly, the OP also states that it does not work.

Moreover, the button does not strictly follows the mouse, so it's just horrible in my opinion.

Now, two things to consider:

  1. You are using evt.getPoint(): the value of that method is relative to the JButton. As you move the JButton around, you cannot compare the value of that method with the previous one (since your button is moving). One simple solution is to convert those points relatively to a fixed panel, for example the parent, which is not moving. Tadaam: it works smoothly now and the button follows your mouse perfectly.
  2. When you use LayoutManager's, you can't call setLocation (nor setBounds or setSize()) because this is the job of LayoutManager's, and as soon as they will re-layout your container, the button will be set back to its original location (which I am guessing you don't want). There are several ways to solve this, but usually, the simplest one is to use absolute positionning (ie, set the layout to null). In the end, this means that you have to perform yourself whatever the LayoutManager was previously doing.

Here is a small demo (which is flawed but demonstrates basic princiles):

import java.awt.Component;
import java.awt.Point;

import javax.swing.SwingUtilities;

/**
 * 
 * @author Stuart.Bradley
 */
public class NewJFrame extends javax.swing.JFrame {
    private Point mouseLocation;

    /**
     * Creates new form NewJFrame
     */
    public NewJFrame() {
        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() {
        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("jButton1");
        jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mousePressed(java.awt.event.MouseEvent evt) {
                jButton1MousePressed(evt);
            }
        });
        jButton1.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            @Override
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                jButton1MouseDragged(evt);
            }
        });
        setLayout(null);
        jButton1.setSize(jButton1.getPreferredSize());
        add(jButton1);
        setSize(300, 300);
    }// </editor-fold>

    private void jButton1MouseDragged(java.awt.event.MouseEvent evt) {
        // current mouse location
        Point newLoc = SwingUtilities.convertPoint(evt.getComponent(), evt.getPoint(), jButton1.getParent());
        // deltas
        int deltaX = newLoc.x - mouseLocation.x;
        int deltaY = newLoc.y - mouseLocation.y;
        jButton1.setLocation(jButton1.getX() + deltaX, jButton1.getY() + deltaY);
        // move the reference point to the current location
        this.mouseLocation = newLoc; // TODO add your handling code here:
    }

    private void jButton1MousePressed(java.awt.event.MouseEvent evt) {
        mouseLocation = SwingUtilities.convertPoint(evt.getComponent(), evt.getPoint(), jButton1.getParent()); // TODO add your
    }

    /**
     * @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(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        // </editor-fold>

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

    // Variables declaration - do not modify
    private javax.swing.JButton jButton1;
    // End of variables declaration
}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117