2016-04-06 12 views
0

私は、クリックしてドラッグすることで画面上で画像を移動できるプログラムを持っています。唯一の問題は、画像をクリックしてパネル上でドラッグすると、画像が最初にマウスカーソルの位置にジャンプすることです。どうすればこの問題を防ぐことができますか?画像をクリックしても画像は単純に移動します。マウスカーソルをドラッグすると、マウスの矢印の下にジャンプするか、ドラッグを開始するときにマウスの矢印の上にドラッグするか、ドラッグするイメージの中央に設定することができます。mouseDraggedを使用しているときに、最初にマウスカーソルの位置にジャンプせずに画像を移動する方法を教えてください。

Iは、以下の機能を別のクラスの画像クラスの画像オブジェクトを移動しています:

xおよびyはmouseDragged法から座標である
moveImage(selected,x,y); 

。 は、これは私のイメージクラスです:あなたが見ることができるように

import javax.imageio.ImageIO; 
import java.awt.*; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 

class Image { 

    private int x; 
    private int y; 
    private BufferedImage image; 
    private StringBuffer filepath; 
    private boolean isTurned; 

    public Image(int x, int y, String filepath) throws IOException { 
     this.filepath = new StringBuffer(filepath); 
     this.x = x; 
     this.y = y; 
     this.image = ImageIO.read(new File(String.valueOf(filepath))); 
    } 

    public void draw(Graphics g){ 

     g.drawImage(image, x, y, null); 

    } 

    public void undraw (Graphics g, Color c){ 
     g.setColor(c); 
     g.fillRect(x,y, image.getWidth(), image.getHeight()); 

    } 

    public boolean containsXY (int x, int y){ 

     if ((this.x <= x) && (x <= (this.x+this.image.getWidth())) && (this.y <= y) && (y <= (this.y+this.image.getHeight())) ){ 

      return true; 
     } 

     return false; 
    } 

    public void move (Graphics g, int x, int y) { 
     System.out.println("int x = " + x + " int y = " + y); 
     System.out.println("this x = " + this.x + " this y = " + this.y); 
     System.out.println("width: " + this.image.getWidth() + " height: " + this.image.getHeight()); 

     undraw(g, Color.WHITE); 

     /* this.x = x - ((x+image.getWidth())-x); 
     this.y = y -((y+image.getHeight())-y); 

     this.x = x - (x-this.x); 
     this.y = y - (y-this.y); 

     this.x = x - (this.x+image.getWidth()-x); 
     this.y = y - (this.y+image.getHeight()-y); 



     this.x = this.x + (x-image.getWidth()); 
     this.y = this.y + (y-image.getHeight()); 

     this.x = x - (image.getWidth()); 
     this.y = y - (image.getHeight());*/ 

     this.x = x - (image.getWidth()/2); 
     this.y = y - (image.getHeight()/2); 


     draw(g); 
    } 

    public void turn(Graphics g) throws IOException { 

     if (isTurned) { 
      filepath.replace(filepath.length()-9, filepath.length(), ".gif"); 
      undraw(g, Color.WHITE); 
      image = ImageIO.read(new File(String.valueOf(filepath))); 
      draw(g); 
      isTurned = false; 
     } 

     else { 
      filepath.replace(filepath.length()-4, filepath.length(), " back.gif"); 
      undraw(g, Color.WHITE); 
      image = ImageIO.read(new File(String.valueOf(filepath))); 
      draw(g); 
      isTurned = true; 
     } 
    } 

} 

、moveメソッドの内部で、私が入ってくるマウスイベントが座標をドラッグ操作に異なるものの多くを試してみました。今のコードで私は現在、できる最善であるの周りをドラッグしていたときに、画像の中央にマウスカーソルロックを作る

this.x = x - (image.getWidth()/2); 
this.y = y - (image.getHeight()/2); 

を使用しています。だから私は画像を移動し、画像の隅をクリックしたいときは、画像の中央に "ポップ"し、そこに画像をドラッグしながらロックします。しかし、私はこれを望んでいません。ドラッグを開始したときにクリックした画像上の位置にマウスカーソルを置いて、別の場所に画像を再描画してからドラッグを開始します。

これ、私はこのクラスの内部で、それを私はImageオブジェクトを呼び出し元のクラスを呼び出すしていますされます。■メソッドのmoveImageを:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Collection; 

class PaintSurface extends JLabel implements MouseListener, MouseMotionListener { 

    private int x, y; 
    private JButton browse; 
    private Collection<Image> images = new ArrayList<Image>(); 
    private final JFileChooser fc = new JFileChooser(); 
    private Image selected; 

    public PaintSurface(JButton b){ 
     browse = b; 
     addMouseListener(this); 
     addMouseMotionListener(this); 
     browse.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 

       int x = fc.showOpenDialog(browse); 

       if (x == JFileChooser.APPROVE_OPTION){ 
        try { 
         buttonPressed(fc); 

        } catch (IOException e1) { 
         e1.printStackTrace(); 
        } 
       } 

       else if (x ==JFileChooser.CANCEL_OPTION){ 
        System.out.println("No file selected."); 
       } 
      } 
     }); 
    } 

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



     for (Image i: images){ 
      i.draw(g); 

     } 


    } 



    public void addImage(Image i){ 

     images.add(i); 
     Graphics g = getGraphics(); 
     i.draw(g); 

    } 

    public void buttonPressed(JFileChooser fc) throws IOException { 

     File selectedFile = fc.getSelectedFile(); 
     String filepath = String.valueOf(selectedFile.getAbsolutePath()); 
     Image i = new Image(x, y, filepath); 
     selected = i; 
     addImage(i); 
     repaint(); 

    } 

    public Image findImage(int x, int y){ 

     Image[] imageArray = images.toArray(new Image[images.size()]); 

     for (int i = imageArray.length - 1; i >= 0; i--){ 
      if (imageArray[i].containsXY(x, y)){ 
       return imageArray[i]; 
      } 
     } 
     return null; 
    } 


    public void moveImage (Image i, int x, int y) { // 

     i.move(getGraphics(), x, y); 
    } 

    public boolean removeImage(Image i){ 

     Graphics g = getGraphics(); 
     i.undraw(g, Color.WHITE); 
     return images.remove(i); 

    } 

    @Override 
    public void mouseClicked(MouseEvent e) { 
     x = e.getX(); 
     y = e.getY(); 
     System.out.println("mouseclick"); 

     selected = findImage(x,y); 

     if (selected != null) { 

      Graphics g = getGraphics(); 

      try { 
       selected.turn(g); 
       repaint(); 
      } catch (IOException e1) { 
       e1.printStackTrace(); 
      } 
      selected = null; 
     } 

    } 

    @Override 
    public void mousePressed(MouseEvent e) { 
     Image i = findImage(e.getX(), e.getY()); 

     if (i == null) { 

      System.out.println("null mousepress"); 
      return; 

     } 

     else { 
      System.out.println("not null mousepress"); 
      if (i == selected){ 
       return; 
      } 
      else { 
       removeImage(i); 
       addImage(i); 
       selected = i; 

      } 


     } 






    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
     int x = e.getX(); 
     int y = e.getY(); 

     if (selected != null) { 
      moveImage(selected,x,y); 
      repaint(); 
     } 
    } 

    @Override 
    public void mouseReleased(MouseEvent e) { 
     selected = null; 
    } 

    @Override 
    public void mouseEntered(MouseEvent e) { 

    } 

    @Override 
    public void mouseExited(MouseEvent e) { 

    } 

    @Override 
    public void mouseMoved(MouseEvent e) { 

    } 
} 

ことができ、このヘルプの経験を持つ誰?私はあなたのPaintSurfaceクラスにオフセットxとyの2つの変数を格納し、このようなfindImage()方法でそれらをinitilizeすることができます...今すぐ週間ほど以来

+0

あなたは画像の '移動()'メソッドを呼び出しているのあるコードを投稿することができますか? – Dimi

+0

答えをくれてありがとう、イメージオブジェクトメソッドと呼ばれる場所からクラスを表示するようにコードを更新しました。 – user5846939

+0

この問題を再現するのに必要な最小限のコードを減らしてください。 –

答えて

1

Imageであなたのmove()方法を変更します。 mousePressedでは、元記者の場所を保存:mouseDragged

// lastX, lastY are object variables 
lastX = e.getX(); 
lastY = e.getY(); 

、デルタを計算

public void mouseDragged(MouseEvent e) { 
    int x = i.getX() + e.getX() - lastX; 
    int y = i.getY() + e.getY() - lastY; 

    if (selected != null) { 
     moveImage(selected,x,y); 
     repaint(); 
    } 
    lastX = e.getX(); 
    lastY = e.getY(); 
} 
+0

ありがとう、私は思ったように問題はイメージクラスの中になかったことを今私は理解しています。 – user5846939

1

をこれで私の髪を引っ張っています:

if (imageArray[i].containsXY(x, y)){ 
    xOffset = x - imageArray[i].getX(); 
    xOffset = y - imageArray[i].getY(); 
    return imageArray[i]; 
} 

そして、あなたはあなたがあなたの代わりに新しいカーソル位置に移動するのクリックした場所からの変更を追跡する必要が

move(Graphics g, int x, int y, int xOffset, int yOffset) { 
    undraw(g, Color.WHITE); 
    this.x = x - xOffset; 
    this.y = y - yOffset; 
    draw(g); 
} 
関連する問題