Java 获取移动JLabel的鼠标坐标

Java 获取移动JLabel的鼠标坐标,java,swing,jpanel,mouselistener,Java,Swing,Jpanel,Mouselistener,我正在做一个项目,开发一个叫做 我有一个JPanel,上面画有形状(圆圈)和JLabel包含图像的组件。我需要每当我单击“掷骰子”(在背景中返回一个介于1和6之间的数字)时,我应该等待当前玩家单击他的一个棋子,并且该棋子应该在n个位置之后移动,其中n等于骰子返回的数字 我的问题是,我应该创建一个等待mouseClick事件的新线程吗?如何获取鼠标单击的坐标 这是我的类,它继承了面板、绘制圆和添加标签 public class ImagePanel extends JPanel{ privat

我正在做一个项目,开发一个叫做

我有一个
JPanel
,上面画有形状(圆圈)和
JLabel
包含图像的组件。我需要每当我单击“掷骰子”(在背景中返回一个介于1和6之间的数字)时,我应该等待当前玩家单击他的一个棋子,并且该棋子应该在n个位置之后移动,其中n等于骰子返回的数字

我的问题是,我应该创建一个等待
mouseClick
事件的新线程吗?如何获取鼠标单击的坐标

这是我的类,它继承了面板、绘制圆和添加标签

public class ImagePanel extends JPanel{

private static final long serialVersionUID = 1L;
ImageMatrix imageMatrix;
BufferedImage[] images;
public static JLabel[][] labels;
DrawGameBoard board = new DrawGameBoard();
List<GameFigure> gameCircles;
List<FinishFigure> finishCircles;
int initialHeight = 528;
int initialWidth = 596;
ThreadForPawnsClick labelsClick;

public ImagePanel(){
    labels = new JLabel[4][4];
    images = new BufferedImage[4];
    setBackground(new Color(255,255,153));
    gameCircles = new ArrayList<GameFigure>();
    finishCircles = new ArrayList<FinishFigure>();
    imageMatrix = new ImageMatrix(initialWidth,initialHeight);

    try {
        images[0] = ImageIO.read(new File("C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\red.png"));
        images[1] = ImageIO.read(new File("C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\green.png"));
        images[2] = ImageIO.read(new File("C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\blue.png"));
        images[3] = ImageIO.read(new File("C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\yellow.png"));
    } catch (IOException e) {
        e.printStackTrace();
    }
    for(int i=0;i<4;i++)
    {
        for(int j=0;j<4;j++)
        labels[i][j] = new JLabel(new ImageIcon(images[i]));
    }
    setLayout(null);
    board.DrawHomeBoard(imageMatrix, labels);
    for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            add(labels[i][j]);
}

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

    int width = this.getWidth();
    int height = this.getHeight();
    imageMatrix.update(width, height);

    setLayout(null);
    gameCircles = board.DrawMainBoard(g, imageMatrix);
    //labels = board.DrawHomeBoard(g, imageMatrix, labels);
    //board.DrawHomeBoard(imageMatrix, labels);
    finishCircles = board.DrawFinishBoard(g, imageMatrix);
    /*for(int i=0;i<4;i++)
        for(int j=0;j<4;j++)
            add(labels[i][j]);
    */
}
}
公共类ImagePanel扩展了JPanel{
私有静态最终长serialVersionUID=1L;
图像矩阵;
BuffereImage[]图像;
公共静态JLabel[][]标签;
DrawGameBoard=新DrawGameBoard();
列出游戏圈;
列出完成循环;
int initialHeight=528;
int initialWidth=596;
ThreadForPawnClick标签Click;
公众影像小组(){
标签=新的JLabel[4][4];
图像=新的缓冲区图像[4];
挫折背景(新颜色(255255153));
gameCircles=新的ArrayList();
finishCircles=新的ArrayList();
imageMatrix=新的imageMatrix(初始宽度、初始高度);
试一试{
images[0]=ImageIO.read(新文件(“C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\red.png”);
images[1]=ImageIO.read(新文件(“C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\green.png”);
images[2]=ImageIO.read(新文件(“C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\blue.png”);
images[3]=ImageIO.read(新文件(“C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\yellow.png”);
}捕获(IOE异常){
e、 printStackTrace();
}
对于(int i=0;i
我的问题是,我应该创建一个等待mouseClick事件的新线程吗

不,绝对不是。相反,您需要以某种方式更改GUI的状态以等待鼠标单击模式,然后根据其状态更改GUI对鼠标单击的响应行为。通常状态由类的实例字段表示。因此,当您需要等待时,您可以更改其中一个状态字段,然后在鼠标单击时检查字段的状态,并根据该状态改变发生的情况。例如,在基于回合的国际象棋游戏中,一个状态字段可以是
private boolean blackTurn
,然后根据其状态确定鼠标的动作

如何获得鼠标点击的坐标

在MouseListener中,MouseEvent参数为您提供鼠标相对于监听组件和屏幕的x和y位置。如果您的MouseListener连接到JLabel,则您可以通过MouseEvent的
getSource()获取对单击的JLabel的引用
方法,然后可以通过调用JLabel上的
getLocation()
来获取JLabel相对于其容器JPanel的位置(如果需要)

旁注:在Swing GUI中,在精灵周围移动时,通常最好不要将精灵放入JLabel中,而是直接在绘图JPanel的paintComponent方法中绘制它们


作为我的意思的一个例子,这里有一个程序,它绘制了4个彩色的圆,这些圆是可拖动的,但只有在JRadioButton设置为“状态”的情况下选择了相应的JRadioButton时才可拖动GUI的。此处状态由名为
ColorState
的枚举表示,该枚举包含4种颜色和相应的文本。以下是此枚举:

import java.awt.Color;

public enum ColorState {
    RED("Red", Color.RED), 
    GREEN("Green", Color.GREEN), 
    BLUE("Blue", Color.BLUE), 
    ORANGE("Orange", Color.ORANGE);

    private String text;
    private Color color;

    private ColorState(String text, Color color) {
        this.text = text;
        this.color = color;
    }

    public String getText() {
        return text;
    }

    public Color getColor() {
        return color;
    }
}
然后我们创建一个图形JPanel,它在一张地图中包含四个椭圆形2D形状的对象

private Map<ColorState, Shape> colorStateMap = new EnumMap<>(ColorState.class);
我们在paintComponent中绘制椭圆:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    // make for smooth graphics
    Graphics2D g2 = (Graphics2D) g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    // iterate through the enum, extracting the ellipse and drawing it
    for (ColorState state : ColorState.values()) {
        Shape shape = colorStateMap.get(state);
        if (shape != null) {
            g2.setColor(state.getColor());
            g2.fill(shape); // draw the ellipse
        }
    }
}   
最后,在MouseAdapter(MouseListener和MouseMotionListener)中,如果单击鼠标左键,并且如果在适当的形状内单击鼠标,我们将侦听鼠标按下并注册成功:

private class MyMouse extends MouseAdapter {
    private Shape selectedShape = null;
    private Point2D offset = null;

    @Override
    public void mousePressed(MouseEvent e) {
        // check that correct button pressed
        if (e.getButton() != MouseEvent.BUTTON1) {
            return;
        }

        // has our colorState been set yet? If not, exit
        if (colorState == null) {
            return;
        }

        // is an appropriate Shape held by the Map? If so, get it
        Shape shape = colorStateMap.get(colorState);
        if (shape == null) {
            return;
        }

        // does this shape contain the point where the mouse was pressed?
        if (!shape.contains(e.getPoint())) {
            return;
        }

        // Get the selected shape, get the mouse point location relative to this shape
        selectedShape = shape;
        double x = e.getX() - shape.getBounds2D().getX();
        double y = e.getY() - shape.getBounds2D().getY();
        offset = new Point2D.Double(x, y);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        // drag shape to new location
        if (selectedShape != null) {
            double x = e.getX() - offset.getX();
            double y = e.getY() - offset.getY();

            Rectangle2D bounds = selectedShape.getBounds2D();
            bounds.setFrame(new Rectangle2D.Double(x, y, bounds.getWidth(), bounds.getHeight()));

            ((Ellipse2D) selectedShape).setFrame(bounds);
            repaint();
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        selectedShape = null;
    }
}   
请注意,鼠标拖动代码要感谢程序员的回答。请投票支持这个答案

整个班级看起来是这样的:

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.EnumMap;
import java.util.Map;
import javax.swing.*;

@SuppressWarnings("serial")
public class StateDependentMouseListener extends JPanel {
    private static final int W = 800;
    private static final int H = 650;
    private static final double CIRCLE_WIDTH = 60.0;
    private ButtonGroup buttonGroup = new ButtonGroup();
    private ColorState colorState = null;
    private Map<ColorState, Shape> colorStateMap = new EnumMap<>(ColorState.class);

    public StateDependentMouseListener() {
        setPreferredSize(new Dimension(W, H));
        for (final ColorState state : ColorState.values()) {
            // create the JRadioButton
            JRadioButton radioButton = new JRadioButton(state.getText());
            add(radioButton); // add to GUI
            buttonGroup.add(radioButton); // add to ButtonGroup

            // give it an ActionListener that changes the object's state
            radioButton.addActionListener(e -> {
                colorState = state;
            });

            // create a randomly placed Ellipse2D and place into Map:
            double x = Math.random() * (W - CIRCLE_WIDTH);
            double y = Math.random() * (H - CIRCLE_WIDTH);
            Ellipse2D ellipse = new Ellipse2D.Double(x, y, CIRCLE_WIDTH, CIRCLE_WIDTH);
            colorStateMap.put(state, ellipse);
        }

        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        // make for smooth graphics
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // iterate through the enum, extracting the ellipse and drawing it
        for (ColorState state : ColorState.values()) {
            Shape shape = colorStateMap.get(state);
            if (shape != null) {
                g2.setColor(state.getColor());
                g2.fill(shape); // draw the ellipse
            }
        }
    }   

    private class MyMouse extends MouseAdapter {
        private Shape selectedShape = null;
        private Point2D offset = null;

        @Override
        public void mousePressed(MouseEvent e) {
            // check that correct button pressed
            if (e.getButton() != MouseEvent.BUTTON1) {
                return;
            }

            // has our colorState been set yet? If not, exit
            if (colorState == null) {
                return;
            }

            // is an appropriate Shape held by the Map? If so, get it
            Shape shape = colorStateMap.get(colorState);
            if (shape == null) {
                return;
            }

            // does this shape contain the point where the mouse was pressed?
            if (!shape.contains(e.getPoint())) {
                return;
            }

            // Get the selected shape, get the mouse point location relative to this shape
            selectedShape = shape;
            double x = e.getX() - shape.getBounds2D().getX();
            double y = e.getY() - shape.getBounds2D().getY();
            offset = new Point2D.Double(x, y);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            // drag shape to new location
            if (selectedShape != null) {
                double x = e.getX() - offset.getX();
                double y = e.getY() - offset.getY();

                Rectangle2D bounds = selectedShape.getBounds2D();
                bounds.setFrame(new Rectangle2D.Double(x, y, bounds.getWidth(), bounds.getHeight()));

                ((Ellipse2D) selectedShape).setFrame(bounds);
                repaint();
            }
        }

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

    private static void createAndShowGui() {
        StateDependentMouseListener mainPanel = new StateDependentMouseListener();

        JFrame frame = new JFrame("StateDependentMouseListener");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.RenderingHints;
导入java.awt.Shape;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.geom.Ellipse2D;
导入java.awt.geom.Point2D;
导入java.awt.geom.Rectangle2D;
导入java.util.EnumMap;
导入java.util.Map;
导入javax.swing.*;
@抑制警告(“串行”)
公共类StateDependentMouseListener扩展了JPanel{
专用静态最终int W=800;
专用静态最终int H=650;
专用静态最终双圈_宽度=60.0;
private ButtonGroup ButtonGroup=新建ButtonGroup();
私有ColorState ColorState=null;
私有映射colorStateMap=新的EnumMap(ColorState.class);
public StateDependentMouseListener(){
设置首选尺寸(新尺寸(W,H));
for(最终颜色状态:ColorState.values()){
//创建JRadioButton
JRadioButton radioButton=newjradiobutton(state.getText());
添加(单选按钮);//添加到GUI
添加(radioButton);//添加到buttonGroup
//给它一个ActionListener来更改对象的状态
radioButton.addActionListener(e->{
颜色状态=状态;
});
//创建一个随机放置的椭圆E2D并放置到地图中:
double x=Math.random()*(W-圆的宽度);
双y=Math.random()*(H-圆的宽度);
Ellipse2D ellipse=新的Ellipse2D.Double(x,y,圆圈宽度,圆圈宽度);
colorStateMap.put(状态,椭圆);
}
MyMouse MyMouse=新建MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
}
@凌驾
受保护组件(图形g){
超级组件(g);
//使光滑
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.EnumMap;
import java.util.Map;
import javax.swing.*;

@SuppressWarnings("serial")
public class StateDependentMouseListener extends JPanel {
    private static final int W = 800;
    private static final int H = 650;
    private static final double CIRCLE_WIDTH = 60.0;
    private ButtonGroup buttonGroup = new ButtonGroup();
    private ColorState colorState = null;
    private Map<ColorState, Shape> colorStateMap = new EnumMap<>(ColorState.class);

    public StateDependentMouseListener() {
        setPreferredSize(new Dimension(W, H));
        for (final ColorState state : ColorState.values()) {
            // create the JRadioButton
            JRadioButton radioButton = new JRadioButton(state.getText());
            add(radioButton); // add to GUI
            buttonGroup.add(radioButton); // add to ButtonGroup

            // give it an ActionListener that changes the object's state
            radioButton.addActionListener(e -> {
                colorState = state;
            });

            // create a randomly placed Ellipse2D and place into Map:
            double x = Math.random() * (W - CIRCLE_WIDTH);
            double y = Math.random() * (H - CIRCLE_WIDTH);
            Ellipse2D ellipse = new Ellipse2D.Double(x, y, CIRCLE_WIDTH, CIRCLE_WIDTH);
            colorStateMap.put(state, ellipse);
        }

        MyMouse myMouse = new MyMouse();
        addMouseListener(myMouse);
        addMouseMotionListener(myMouse);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        // make for smooth graphics
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // iterate through the enum, extracting the ellipse and drawing it
        for (ColorState state : ColorState.values()) {
            Shape shape = colorStateMap.get(state);
            if (shape != null) {
                g2.setColor(state.getColor());
                g2.fill(shape); // draw the ellipse
            }
        }
    }   

    private class MyMouse extends MouseAdapter {
        private Shape selectedShape = null;
        private Point2D offset = null;

        @Override
        public void mousePressed(MouseEvent e) {
            // check that correct button pressed
            if (e.getButton() != MouseEvent.BUTTON1) {
                return;
            }

            // has our colorState been set yet? If not, exit
            if (colorState == null) {
                return;
            }

            // is an appropriate Shape held by the Map? If so, get it
            Shape shape = colorStateMap.get(colorState);
            if (shape == null) {
                return;
            }

            // does this shape contain the point where the mouse was pressed?
            if (!shape.contains(e.getPoint())) {
                return;
            }

            // Get the selected shape, get the mouse point location relative to this shape
            selectedShape = shape;
            double x = e.getX() - shape.getBounds2D().getX();
            double y = e.getY() - shape.getBounds2D().getY();
            offset = new Point2D.Double(x, y);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            // drag shape to new location
            if (selectedShape != null) {
                double x = e.getX() - offset.getX();
                double y = e.getY() - offset.getY();

                Rectangle2D bounds = selectedShape.getBounds2D();
                bounds.setFrame(new Rectangle2D.Double(x, y, bounds.getWidth(), bounds.getHeight()));

                ((Ellipse2D) selectedShape).setFrame(bounds);
                repaint();
            }
        }

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

    private static void createAndShowGui() {
        StateDependentMouseListener mainPanel = new StateDependentMouseListener();

        JFrame frame = new JFrame("StateDependentMouseListener");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}