2012-01-03 3 views
3

Что я хочу, чтобы этот код выполнял, когда я нажимаю и перетаскиваю красный шар на экране, я хочу, чтобы он двигался с помощью курсора мыши, этот код выполняет эту работу и частично берется из кода Sun, поэтому он должен быть эффективным, но все же, если я слишком быстро передвигаю мышь, он перестает рисовать мышью ...MouseDragging in GUI

как я могу это преодолеть?

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 «больше.

Исправить эту проблему - использовать логическую переменную с статусом mouseButton, если щелкнуть мышью внутри круга, вы сделаете круг с помощью мыши в любом месте! Если парень отпускает кнопку мыши, ваша мышь просто перемещается.

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

спасибо, в чем была проблема? –

+0

Проверки ограничений в методе перетаскивания мышью не были в состоянии идти в ногу с движением мыши. ;) –