【发布时间】:2016-04-06 12:11:33
【问题描述】:
我有一个程序,我可以通过单击和拖动在屏幕上移动图像。唯一的问题是,当我单击图像并开始在面板上拖动它时,图像首先会跳转到鼠标光标的位置。我该如何防止这种情况,以便无论我在哪里单击图像,图像都会被简单地移动?我只能让鼠标光标在开始拖动时跳到鼠标箭头下方,或者在开始拖动时跳到鼠标箭头上方,或者设置到要拖动的图像中间。
我正在使用以下函数在另一个类中移动 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) {
}
}
有这方面经验的人可以帮忙吗?大约一个星期以来,我一直在用这个拉头发……
【问题讨论】:
-
你能贴出你调用 Image 的
move()方法的代码吗? -
感谢您的回答,我更新了代码以显示我调用图像对象方法的类。
-
请将您的代码减少到重现此问题所需的最低限度。
标签: java