优化拖动代码

时间:2013-01-30 21:12:02

标签: java swing mouseevent draggable

所以我发现这段代码here,它起作用,它只会导致相当多的抖动 - (拖动的速度越快,图像抖动越多) - 在图像被拖动时。 OP表示它没有进行优化,因为它是一个死的帖子我以为我会看到这里是否有人可以提供帮助!我也试过了stack的代码,但我无法做任何事情。如果有人对此代码有任何建议,或者我希望听到更好的解决方案!

注意,我的Jpanel需要被拖动(paintComponent绘制的对象)在一个滚动窗格内!

   //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是一个示例程序,显示了抖动!

1 个答案:

答案 0 :(得分:3)

  

所以我在这里发现了这个代码,它起作用了,它只会导致很多抖动

然后我会说它不起作用。如果你仔细阅读帖子,OP也会说它不起作用。

此外,按钮并不严格遵循鼠标,所以在我看来它太可怕了。

现在,需要考虑两件事:

  1. 您正在使用evt.getPoint():该方法的值相对于JButton。当您移动JButton时,您无法将该方法的值与前一个方法的值进行比较(因为您的按钮正在移动)。一个简单的解决方案是将这些点相对转换为固定的面板,例如不移动的父面板。 Tadaam:它现在运行顺畅,按钮完全跟随你的鼠标。
  2. 当您使用LayoutManager时,您无法调用setLocation(也不能调用setBounds或setSize()),因为这是LayoutManager的工作,并且只要它们将重新布置容器,按钮将被设置回原来的位置(我猜你不想要)。有几种方法可以解决这个问题,但通常最简单的方法是使用绝对定位(即将布局设置为null)。最后,这意味着您必须自己执行LayoutManager以前所做的任何事情。
  3. 这是一个小型演示(有缺陷但演示基本原理):

    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
    }
    
相关问题