2012-10-17 55 views
1

我正試圖在畫布上實現形狀的拖動功能。我的Shape類繼承自JPanelJava中的對象問題

當我點擊一個形狀,拖動它並放開鼠標按鈕時,絕對沒有任何反應。它只是它原來的地方。有任何想法嗎?

+1

退房[ComponentMover](http://tips4java.wordpress.com/2009/06/14/moving-windows/)。 – tenorsax

+0

getSelectedShape()中的代碼是否可以在鼠標單擊時獲得正確的形狀對象? –

+0

是的,我測試過它,它工作。 @ sampson-chen –

回答

3

你需要一些基本的東西:

  1. 用於本身的形狀場(你已經有了)
  2. 字段跟蹤的點擊形狀中的偏移量(已有)
  3. 字段來跟蹤,如果你拖
  4. 覆蓋的paintComponent方法來畫你的形狀
  5. 一個MouseListenerMouseMotionListener添加到面板(MouseAdapter做這兩個)

這是一個基本的工作示例。

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

public class DrawTest extends JPanel{ 

    //Shape doesn't have a location field - you'd have to keep track of 
    //this yourself if you're set on using the shape interface 
    private Rectangle shape = new Rectangle(100, 100); 
    // The location within the shape you clicked 
    private int xOffset = 0; 
    private int yOffset = 0; 
    // To indicate dragging is happening 
    boolean isDragging = false; 

    public DrawTest(){ 
     MouseAdapter listener = new MouseAdapter() { 

      @Override 
      public void mousePressed(MouseEvent e) { 
       // Starts dragging and calculates offset 
       if(shape.contains(e.getPoint())){ 
        isDragging = true; 
        xOffset = e.getPoint().x - shape.x; 
        yOffset = e.getPoint().y - shape.y; 
       } 
      } 

      @Override 
      public void mouseReleased(MouseEvent e) { 
       // Ends dragging 
       isDragging = false; 
      } 


      @Override 
      public void mouseDragged(MouseEvent e) { 
       // Moves the shape - doesn't actually need to be a method 
       // but is because you had it as one 
       if(isDragging){ 
        moveShape(e); 
       } 
      } 

      private void moveShape(MouseEvent e) { 
       Point newLocation = e.getPoint(); 
       newLocation.x -= xOffset; 
       newLocation.y -= yOffset; 
       shape.setLocation(newLocation); 
       repaint(); 
      } 
     }; 

     //Add a mouse mostion listener (for dragging) and regular listener (for clicking) 
     addMouseListener(listener); 
     addMouseMotionListener(listener); 
    } 

    // So we have a play area to work with 
    public Dimension getPreferredSize(){ 
     return new Dimension(400,300); 
    } 

    //Paints the shape 
    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 
     g.clearRect(0,0,getWidth(), getHeight()); 
     g.fillRect(shape.x, shape.y, shape.width, shape.height); 
    } 


    public static void main(String[] args) 
    { 

     final JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new DrawTest()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 

    } 
} 
+0

+1個很好的例子(當我的硬盤死亡時,我失去了我自己的例子:0) –

+1

@DavidKroukamp這是丟失任何東西的最糟糕的方式 - 你有我的哀悼......(沉默片刻爲已故) –

+0

仍然沒有解決問題,但感謝您的幫助 –

3

嘗試了小簡單的例子

拖動矩形將使它與光標它還檢查邊界移動,從而該矩形不能被拖離屏幕:

enter image description here

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class ShapeMover { 

    public ShapeMover() { 

     JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setTitle("Shape Mover"); 
     initComponents(frame); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String s[]) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new ShapeMover(); 
      } 
     }); 

    } 

    private void initComponents(JFrame frame) { 
     frame.getContentPane().add(new DragPanel()); 
    } 
} 

class DragPanel extends JPanel { 

    Rectangle rect = new Rectangle(0, 0, 100, 50); 
    int preX, preY; 
    boolean isFirstTime = true; 
    Rectangle area; 
    boolean pressOut = false; 
    private Dimension dim = new Dimension(400, 300); 

    public DragPanel() { 
     setBackground(Color.white); 
     addMouseMotionListener(new MyMouseAdapter()); 
     addMouseListener(new MyMouseAdapter()); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return dim; 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     Graphics2D g2d = (Graphics2D) g; 
     if (isFirstTime) { 
      area = new Rectangle(dim); 
      rect.setLocation(50, 50); 
      isFirstTime = false; 
     } 

     g2d.setColor(Color.black); 
     g2d.fill(rect); 
    } 

    boolean checkRect() { 
     if (area == null) { 
      return false; 
     } 

     if (area.contains(rect.x, rect.y, 100, 50)) { 
      return true; 
     } 
     int new_x = rect.x; 
     int new_y = rect.y; 

     if ((rect.x + 100) > area.getWidth()) { 
      new_x = (int) area.getWidth() - 99; 
     } 
     if (rect.x < 0) { 
      new_x = -1; 
     } 
     if ((rect.y + 50) > area.getHeight()) { 
      new_y = (int) area.getHeight() - 49; 
     } 
     if (rect.y < 0) { 
      new_y = -1; 
     } 
     rect.setLocation(new_x, new_y); 
     return false; 
    } 

    private class MyMouseAdapter extends MouseAdapter { 

     @Override 
     public void mousePressed(MouseEvent e) { 
      preX = rect.x - e.getX(); 
      preY = rect.y - e.getY(); 

      if (rect.contains(e.getX(), e.getY())) { 
       updateLocation(e); 
      } else { 
       pressOut = true; 
      } 
     } 

     @Override 
     public void mouseDragged(MouseEvent e) { 
      if (!pressOut) { 
       updateLocation(e); 
      } else { 
      } 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
      if (rect.contains(e.getX(), e.getY())) { 
       updateLocation(e); 
      } else { 
       pressOut = false; 
      } 
     } 

     public void updateLocation(MouseEvent e) { 
      rect.setLocation(preX + e.getX(), preY + e.getY()); 
      checkRect(); 

      repaint(); 
     } 
    } 
} 

參考:

通過@camickr