[英]How do I get the mouse position on click when it is outside of the component?
[英]How do I get images to move without them first jumping to position of the mouse cursor when using mouseDragged?
我有一個程序,可以通過單擊和拖動在屏幕上移動圖像。 唯一的問題是,當我單擊圖像並開始在面板上拖動圖像時,圖像首先跳到鼠標光標的位置。 如何防止這種情況發生,以便無論我在哪里單擊圖像都可以簡單地移動圖像? 我只能使鼠標光標在開始拖動時跳到鼠標箭頭下方,或者在開始拖動時跳到鼠標箭頭上方,或者設置為要拖動圖像的中間位置。
我正在使用以下功能在另一個類中移動Image類的Image對象:
moveImage(selected,x,y);
其中x和y是mouseDragged方法的坐標。 這是我的圖像類:
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對象的類,我在該類的s方法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偏移量的兩個變量,並在findImage()
方法中將其findImage()
如下所示:
if (imageArray[i].containsXY(x, y)){
xOffset = x - imageArray[i].getX();
xOffset = y - imageArray[i].getY();
return imageArray[i];
}
然后, move()
Image
move()
方法更改為
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);
}
您需要從單擊位置跟蹤更改,而不是移動到新的光標位置。 在mousePressed
,存儲原始按位置:
// lastX, lastY are object variables
lastX = e.getX();
lastY = e.getY();
在mouseDragged
,計算增量
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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.