我在JLabel中有一个图像。
JLabel label = new JLabel(new ImageIcon("C:\\image.jpg"));
label.setSize(300,300);
我想要以下功能。
- 我点击JLabel内的一个位置(在图像上)。
- 按下鼠标按钮,我可以在JLabel中更改图像的位置。 (我将图片拖到JLabel内的不同位置)
嗯,这意味着在很多情况下,图片将被裁剪并在视图之外。
请告诉我如何实现此功能?
要添加到JLabel的正确事件侦听器是什么?
答案 0 :(得分:4)
首先,我建议使用布局而不是setLayout(null)和setBounds()。其次,从JLabel中分离ImageIcon。最后,将JLabel和ImageIcon设置为字段而不是局部变量。
您需要添加MouseListener和MouseMotionListener。
label.addMouseMotionListener(new MouseAdapter()
{
public void mouseMoved(MouseEvent arg0)
{
if(clicked)
{
label.x++
label.y++
label.repaint();
}
}
});
label.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent arg0)
{
clicked = !clicked;
}
});
(对不起事先提出罗嗦)
这会使标签的图像出现在标签所在的位置,当您将鼠标悬停在标签上时,它将向东南方向移动。我创建了一个新的标签类,我在其中覆盖paintComponent并在其中添加了一个绘图图标图标方法,其中x和y是变量。想法是计算标签上的中心点,然后向西移动该点(x--)向西移动图像的x位置,向南移动(y--),等等。这只会在标签内移动您的图像。如果您的鼠标位于标签之外,则移动会停止。如果图像的某些部分位于标签之外,则不会显示该部分。我会覆盖你的标签类中的paint compoent并移动图像,然后为每个动作设置图标。
public class Label1 extends JLabel
{
public int x;
public int y;
ImageIcon imageIcon = new ImageIcon("path");
public void paintComponent(Graphics g)
{
super.paintComponent(g);
//No setLocation(x, y) method exists for an image icon or an image. You are on your own on this
imageIcon.setLocation(x, y);
label.setIcon(imageIcon);
}
}
答案 1 :(得分:4)
这是一个基本的例子......
它的工作原理是将标签分成3x3网格,其中每个单元格代表图标的可能位置。
public class TestMouseDrag {
public static void main(String[] args) {
new TestMouseDrag();
}
public TestMouseDrag() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DragMyIcon());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected class DragMyIcon extends JPanel {
private JLabel label;
public DragMyIcon() {
ImageIcon icon = null;
try {
icon = new ImageIcon(ImageIO.read(getClass().getResource("/bomb.png")));
} catch (IOException ex) {
ex.printStackTrace();
}
label = new JLabel(icon);
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
setLayout(new BorderLayout());
add(label);
MouseHandler handler = new MouseHandler();
label.addMouseListener(handler);
label.addMouseMotionListener(handler);
}
}
protected class MouseHandler extends MouseAdapter {
private boolean active = false;
@Override
public void mousePressed(MouseEvent e) {
JLabel label = (JLabel) e.getComponent();
Point point = e.getPoint();
active = getIconCell(label).contains(point);
if (active) {
label.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
} else {
label.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
@Override
public void mouseReleased(MouseEvent e) {
active = false;
JLabel label = (JLabel) e.getComponent();
label.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
@Override
public void mouseDragged(MouseEvent e) {
if (active) {
JLabel label = (JLabel) e.getComponent();
Point point = e.getPoint();
int verticalAlign = label.getVerticalAlignment();
int horizontalAlign = label.getHorizontalAlignment();
if (isWithInColumn(label, point, 0)) {
horizontalAlign = JLabel.LEFT;
} else if (isWithInColumn(label, point, 1)) {
horizontalAlign = JLabel.CENTER;
} else if (isWithInColumn(label, point, 2)) {
horizontalAlign = JLabel.RIGHT;
}
if (isWithInRow(label, point, 0)) {
verticalAlign = JLabel.TOP;
} else if (isWithInRow(label, point, 1)) {
verticalAlign = JLabel.CENTER;
} else if (isWithInRow(label, point, 2)) {
verticalAlign = JLabel.BOTTOM;
}
label.setVerticalAlignment(verticalAlign);
label.setHorizontalAlignment(horizontalAlign);
label.invalidate();
label.repaint();
}
}
@Override
public void mouseMoved(MouseEvent e) {
}
protected boolean isWithInColumn(JLabel label, Point p, int gridx) {
int cellWidth = label.getWidth() / 3;
int cellHeight = label.getHeight();
Rectangle bounds = new Rectangle(gridx * cellWidth, 0, cellWidth, cellHeight);
return bounds.contains(p);
}
protected boolean isWithInRow(JLabel label, Point p, int gridY) {
int cellWidth = label.getWidth();
int cellHeight = label.getHeight() / 3;
Rectangle bounds = new Rectangle(0, cellHeight * gridY, cellWidth, cellHeight);
return bounds.contains(p);
}
private Rectangle getIconCell(JLabel label) {
Rectangle bounds = new Rectangle();
int cellWidth = label.getWidth() / 3;
int cellHeight = label.getHeight() / 3;
bounds.width = cellWidth;
bounds.height = cellHeight;
if (label.getHorizontalAlignment() == JLabel.LEFT) {
bounds.x = 0;
} else if (label.getHorizontalAlignment() == JLabel.CENTER) {
bounds.x = cellWidth;
} else if (label.getHorizontalAlignment() == JLabel.RIGHT) {
bounds.x = cellWidth * 2;
} else {
bounds.x = 0;
bounds.width = 0;
}
//if (label.getHorizontalAlignment() == JLabel.TOP) {
// bounds.y = 0;
//} else if (label.getHorizontalAlignment() == JLabel.CENTER) {
// bounds.y = cellHeight;
//} else if (label.getHorizontalAlignment() == JLabel.BOTTOM) {
// bounds.y = cellHeight * 2;
//} else {
// bounds.y = 0;
// bounds.height = 0;
//}
if (label.getVerticalAlignment() == JLabel.TOP) {
bounds.y = 0;
} else if (label.getVerticalAlignment() == JLabel.CENTER) {
bounds.y = cellHeight;
} else if (label.getVerticalAlignment() == JLabel.BOTTOM) {
bounds.y = cellHeight * 2;
} else {
bounds.y = 0;
bounds.height = 0;
}
return bounds;
}
}
}
根据反馈更新
此示例基本上使用JLayerdPane
来允许在其容器中重新定位JLabels
...
public class MoveMe {
public static void main(String[] args) {
new MoveMe();
}
public MoveMe() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new MoveMePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MoveMePane extends JLayeredPane {
public MoveMePane() {
int width = 400;
int height = 400;
for (int index = 0; index < 10; index++) {
String text = "Label " + index;
JLabel label = new JLabel(text);
label.setSize(label.getPreferredSize());
int x = (int) Math.round(Math.random() * width);
int y = (int) Math.round(Math.random() * height);
if (x + label.getWidth() > width) {
x = width - label.getWidth();
}
if (y + label.getHeight() > width) {
y = width - label.getHeight();
}
label.setLocation(x, y);
add(label);
}
MoveMeMouseHandler handler = new MoveMeMouseHandler();
addMouseListener(handler);
addMouseMotionListener(handler);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
}
public class MoveMeMouseHandler extends MouseAdapter {
private int xOffset;
private int yOffset;
private JLabel draggy;
private String oldText;
@Override
public void mouseReleased(MouseEvent me) {
if (draggy != null) {
draggy.setText(oldText);
draggy.setSize(draggy.getPreferredSize());
draggy = null;
}
}
public void mousePressed(MouseEvent me) {
JComponent comp = (JComponent) me.getComponent();
Component child = comp.findComponentAt(me.getPoint());
if (child instanceof JLabel) {
xOffset = me.getX() - child.getX();
yOffset = me.getY() - child.getY();
draggy = (JLabel) child;
oldText = draggy.getText();
draggy.setText("What a drag");
draggy.setSize(draggy.getPreferredSize());
}
}
public void mouseDragged(MouseEvent me) {
if (draggy != null) {
draggy.setLocation(me.getX() - xOffset, me.getY() - yOffset);
}
}
}
}
答案 2 :(得分:1)
此修改示例基于MadProgrammer的代码。
它显示了我在原帖中描述的行为。谢谢大家的宝贵帮助,特别是MadProgrammer和Coupon22。尝试一下。
import java.awt.*;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
public class TestMouseDrag {
public static void main(String[] args) {
new TestMouseDrag();
}
public TestMouseDrag() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new DragMyIcon("C://image.jpg"));
frame.pack();
frame.setSize(500,500);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected class DragMyIcon extends JPanel {
public static final long serialVersionUID = 172L;
private JLabel label;
public DragMyIcon(String path) {
setLayout(null);
ImageIcon icon = null;
icon = new ImageIcon(path);
label = new JLabel(icon);
label.setBounds(0,0,icon.getIconWidth(), icon.getIconHeight());
setBounds(0,0,icon.getIconWidth(), icon.getIconHeight());
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
add(label);
MouseHandler handler = new MouseHandler();
label.addMouseListener(handler);
label.addMouseMotionListener(handler);
}
}
protected class MouseHandler extends MouseAdapter {
private boolean active = false;
private int xDisp;
private int yDisp;
@Override
public void mousePressed(MouseEvent e) {
active = true;
JLabel label = (JLabel) e.getComponent();
xDisp = e.getPoint().x - label.getLocation().x;
yDisp = e.getPoint().y - label.getLocation().y;
label.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
}
@Override
public void mouseReleased(MouseEvent e) {
active = false;
JLabel label = (JLabel) e.getComponent();
label.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
@Override
public void mouseDragged(MouseEvent e) {
if (active) {
JLabel label = (JLabel) e.getComponent();
Point point = e.getPoint();
label.setLocation(point.x - xDisp, point.y - yDisp);
label.invalidate();
label.repaint();
}
}
@Override
public void mouseMoved(MouseEvent e) {
}
}
}