2012-01-03 59 views
3

我想要這段代碼做的事情是當我按下並拖動屏幕上的紅色球時,我希望它隨鼠標光標移動,此代碼完成這項工作,並部分取自Sun代碼,所以它是假設是有效的,但如果我移動鼠標太快,它會停止拖動鼠標...在GUI中的MouseDragging

我該如何克服這一點?

public class SwingPaintDemo3 { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 

    private static void createAndShowGUI() { 
     JFrame f = new JFrame("Swing Paint Demo"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new MyPanel()); 
     f.pack(); 
     f.setVisible(true); 
    } 
} 

class MyPanel extends JPanel { 

    private int X = 0; 
    private int Y = 0; 
    private int R = 20; 


     public MyPanel() { 

     addMouseListener(new MouseAdapter() { 
      public void mousePressed(MouseEvent e) { 
       if ((X<=e.getX() && X+R>=e.getX()) && (Y<=e.getY() && Y+R>=e.getY())) moveVertex(e.getX(),e.getY()); 
      } 
     }); 

     addMouseMotionListener(new MouseAdapter() { 
      public void mouseDragged(MouseEvent e) { 
       if ((X<=e.getX() && X+R>=e.getX()) && (Y<=e.getY() && Y+R>=e.getY())) moveVertex(e.getX(),e.getY()); 
      } 
     }); 

    } 

    private void moveVertex(int x, int y) { 
     int OFFSET = 1; 
     if ((X!=x) || (Y!=y)) { 
      repaint(X,Y,R+OFFSET,R+OFFSET); 
      X=x-10; 
      Y=y-10; 
      repaint(X,Y,R+OFFSET,R+OFFSET); 
     } 
    } 


    public Dimension getPreferredSize() { 
     return new Dimension(250,200); 
    } 

    protected void paintComponent(Graphics g) { 
     super.paintComponent(g);  
     g.drawString("This is my custom Panel!",10,20); 
     g.setColor(Color.RED); 
     g.fillOval(X,Y,R,R); 
     g.setColor(Color.BLACK); 
     g.drawOval(X,Y,R,R); 
    } 
} 

回答

4

此問題的原因是事件處理Java的線程是不夠快,無法處理的mouseDragged事件,當你把鼠標移動速度太快。因此,假設你的鼠標指針位於圓圈的中心,但是你在某些方向上移動它的速度非常快,所以mouseDragged事件只有當鼠標位於圓形區域外時纔會觸發,因此鼠標指針不是「與cicle 「了。

解決此問題的方法是在鼠標按鈕狀態下使用布爾變量,如果鼠標在圓形內部單擊,您將使圓形隨鼠標隨處移動!如果傢伙放開鼠標按鈕,鼠標就會移動。

class MyPanel extends JPanel { 
     ... 
     private boolean holdedInsideCircle = false; 


      public MyPanel() { 

       addMouseListener(new MouseAdapter() { 
        public void mousePressed(MouseEvent e) { 
        if ((X<=e.getX() && X+R>=e.getX()) && (Y<=e.getY() && Y+R>=e.getY())) 
         moveVertex(e.getX(),e.getY()); 
         holdedInsideCircle = true; 
        } 
        @Override 
        public void mouseReleased(MouseEvent e) { 
         //Doesn't matter where, if the mouse button is released 
         holdedInsideCircle = false; 
        } 
       }); 


       addMouseMotionListener(new MouseAdapter() { 
        public void mouseDragged(MouseEvent e) { 
         //if ((X<=e.getX() && X+R>=e.getX()) && (Y<=e.getY() && Y+R>=e.getY())) 
         if(holdedInsideCircle) 
          moveVertex(e.getX(),e.getY()); 
        } 
       }); 

     } 
4

試試這個變種。

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

public class SwingPaintDemo3 { 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 

    private static void createAndShowGUI() { 
     JFrame f = new JFrame("Swing Paint Demo"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(new MyPanel()); 
     f.pack(); 
     f.setVisible(true); 
    } 
} 

class MyPanel extends JPanel { 

    private int X = 0; 
    private int Y = 0; 
    private int R = 20; 
    private boolean isDrag = false; 

    public MyPanel() { 
     addMouseListener(new MouseAdapter() { 
      @Override 
      public void mousePressed(MouseEvent e) { 
       if ((X<=e.getX() && X+R>=e.getX()) && (Y<=e.getY() && Y+R>=e.getY())) { 
        moveVertex(e.getX(),e.getY()); 
        isDrag = true; 
       } 
      } 

      @Override 
      public void mouseReleased(MouseEvent e) { 
       isDrag = false; 
      } 
     }); 

     addMouseMotionListener(new MouseAdapter() { 
      @Override 
      public void mouseDragged(MouseEvent e) { 
       if (isDrag) moveVertex(e.getX(),e.getY()); 
      } 
     }); 
    } 

    private void moveVertex(int x, int y) { 
     int OFFSET = 1; 
     if ((X!=x) || (Y!=y)) { 
      repaint(X,Y,R+OFFSET,R+OFFSET); 
      X=x-10; 
      Y=y-10; 
      repaint(X,Y,R+OFFSET,R+OFFSET); 
     } 
    } 

    public Dimension getPreferredSize() { 
     return new Dimension(250,200); 
    } 

    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawString("This is my custom Panel!",10,20); 
     g.setColor(Color.RED); 
     g.fillOval(X,Y,R,R); 
     g.setColor(Color.BLACK); 
     g.drawOval(X,Y,R,R); 
    } 
} 
+0

謝謝,這是什麼問題? – 2012-01-03 18:19:27

+0

鼠標拖動方法中的約束檢查無法跟上鼠標的移動。 ;) – 2012-01-03 18:20:59