我尝试让 JPanel 组件可以从我观看的 YT 视频中拖动,问题是即使我的鼠标没有直接位于面板上方,它也会拖动面板。我还尝试在网上查找如何设置拖动的界限,但我找不到任何内容。我想知道是否有人有解决方案。
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
public class DragPanel extends JPanel {
ImageIcon image = new ImageIcon("A:\\Aseprite\\Saves\\Blue Log.png");
Point imageCorner;
Point prePt;
DragPanel() {
imageCorner = new Point(0,0);
ClickListener clickListener = new ClickListener();
DragListener dragListener = new DragListener();
this.addMouseListener(clickListener);
this.addMouseMotionListener(dragListener);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
image.paintIcon(this, g,(int)imageCorner.getX(),(int)imageCorner.getY());
}
private class ClickListener extends MouseAdapter {
public void mousePressed(MouseEvent e) {
prePt = e.getPoint();
}
}
private class DragListener extends MouseMotionAdapter {
public void mouseDragged(MouseEvent e) {
Point currentPt = e.getPoint();
imageCorner.translate(((int)(currentPt.getX() - prePt.getX())), (int)(currentPt.getY() - prePt.getY()));
prePt = currentPt;
repaint();
}
}
}
Oracle 有一个有用的教程,使用 Swing 创建 GUI。 跳过使用 NetBeans IDE 学习 Swing 部分。
问题中发布的代码创建了一个JPanel
。 为了使代码可以运行,我添加了一些代码。这是我创建的 GUI 的图像。
我在网上找到了一张图片。 我添加了一个
JFrame
来固定
JPanel
。修改了
mousePressed
方法以检查按下的点是否在图像的边界内。 修改了
mouseDragged
方法来检查按下的点是否有效。这是完整的可运行代码。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DragPanelExample implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new DragPanelExample());
}
@Override
public void run() {
JFrame frame = new JFrame("DragPanel Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DragPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public class DragPanel extends JPanel {
private static final long serialVersionUID = 1L;
ImageIcon image;
Point imageCorner;
Point prePt;
public DragPanel() {
this.imageCorner = new Point(0, 0);
this.image = getImage("https://www.wallpaperflare.com/static/"
+ "454/537/313/wood-texture-blue-tree-wallpaper.jpg");
this.setPreferredSize(new Dimension(960, 540));
ClickListener clickListener = new ClickListener();
DragListener dragListener = new DragListener();
this.addMouseListener(clickListener);
this.addMouseMotionListener(dragListener);
}
private ImageIcon getImage(String urlString) {
try {
@SuppressWarnings("deprecation")
URL url = new URL(urlString);
Image image = ImageIO.read(url);
Image smallImage = image.getScaledInstance(192, 108,
Image.SCALE_SMOOTH);
return new ImageIcon(smallImage);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
image.paintIcon(this, g, (int) imageCorner.getX(),
(int) imageCorner.getY());
}
private class ClickListener extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e) {
Point currentPt = e.getPoint();
if (currentPt.x <= (imageCorner.x + image.getIconWidth())
&& (currentPt.x >= imageCorner.x)
&& (currentPt.y <= (imageCorner.y + image.getIconHeight())
&& (currentPt.y >= imageCorner.y))) {
prePt = e.getPoint();
} else {
prePt = null;
}
}
}
private class DragListener extends MouseMotionAdapter {
@Override
public void mouseDragged(MouseEvent e) {
if (prePt != null) {
Point currentPt = e.getPoint();
imageCorner.translate(
((int) (currentPt.getX() - prePt.getX())),
(int) (currentPt.getY() - prePt.getY()));
prePt = currentPt;
repaint();
}
}
}
}
}