Java Swing mousePressed和getSource()未在JPanel上显示绘制的形状

Java Swing mousePressed和getSource()未在JPanel上显示绘制的形状,java,swing,jpanel,shapes,mouselistener,Java,Swing,Jpanel,Shapes,Mouselistener,我目前正在尝试开发一个谜题。我得到的只是我的应用程序和我的游戏场地和游戏部件。下一步是点击我的一个游戏块来选择它,并能够用箭头键移动它(此外,如果下一步(100像素)不包含任何其他游戏块,我只想让它们移动) 我目前遇到的问题是:在我的主JPanel上使用addMouseListener(),然后使用getSource()只返回我的游戏场(在我的代码中称为View),但我需要它来返回所需的游戏块(例如topLeft)。我已经尝试将getSource()转换为Piece,但这不起作用(无法将视图转换

我目前正在尝试开发一个谜题。我得到的只是我的应用程序和我的游戏场地和游戏部件。下一步是点击我的一个游戏块来选择它,并能够用箭头键移动它(此外,如果下一步(100像素)不包含任何其他游戏块,我只想让它们移动)

我目前遇到的问题是:在我的主
JPanel
上使用
addMouseListener()
,然后使用
getSource()
只返回我的游戏场(在我的代码中称为
View
),但我需要它来返回所需的游戏块(例如
topLeft
)。我已经尝试将
getSource()
转换为
Piece
,但这不起作用(
无法将视图转换为Piece

因此,我需要找到一种方法来添加一个鼠标侦听器,它返回单击的游戏块,以便我可以更改位置并检查与任何其他游戏块的任何碰撞。提前谢谢

通过@camickr编辑代码

导入java.awt.Color;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Polygon;
导入java.awt.Rectangle;
导入java.awt.Shape;
导入java.awt.event.MouseAdapter;
导入java.awt.event.MouseEvent;
导入java.awt.geom.AffineTransform;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.SwingUtilities;
公共类难题{
公共静态void main(字符串[]args){
调用器(Puzzle::new);
}
私有最终静态int[]SHAPE_X={-100100100,0,0,-100};
私有最终静态int[]SHAPE_Y={-100,-100,0,01000};
公共拼图(){
JFrame=新的JFrame(“拼图”);
框架。设置尺寸(400600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
视图=新视图();
frame.setContentPane(视图);
view.addMouseListener(新的MouseAdapterMod(视图));
Shape polyShape=新多边形(Shape_X,Shape_Y,Shape_X.length);
工件左上方=新工件(颜色为黄色,多边形,0,100,100);
视图.片段.添加(左上角);
工件右上方=新工件(颜色为青色,多边形,90300100);
view.parties.add(右上角);
工件底部右=新工件(颜色:绿色,多边形,180,300,300);
view.pieces.add(右下角);
工件底部左=新工件(颜色:红色,多边形,270,100,300);
view.pieces.add(左下角);
方块=新的方块(颜色为橙色,新的矩形(200200),01000);
视图。块。添加(方形);
frame.setVisible(true);
}
}
类视图扩展了JPanel{
最终列表项=新的ArrayList();
@凌驾
受保护组件(图形g){
超级组件(g);
Graphics2D gc=(Graphics2D)g;
用于(件:件){
计件图(gc);
}
}
}
班级作品{
最终颜色;
最终形状;
最终内倾角;
int x;
int-y;
工件(颜色、形状、整型角度、整型x、整型y){
这个颜色=颜色;
这个形状=形状;
这个角度=角度;
这个.x=x;
这个。y=y;
}
无效绘图(图形2D gc){
仿射变换tf=gc.getTransform();
gc.translate(x,y);
旋转(数学托拉面(角度));
gc.setColor(color);
填充(形状);
gc.setTransform(tf);
}
Shape getShape(){
返回形状;
}
}
类MouseAdapterMod扩展了MouseAdapter{
最终视图;
公共MouseAdapterMod(视图){
this.view=视图;
}
@凌驾
公共无效鼠标按下(MouseEvent e){
for(工件:视图.工件){
if(piece.getShape()包含(e.getX(),e.getY()){
System.out.println(“是”);
}
}
}
}
因此,我需要找到一种方法来添加一个鼠标侦听器,该侦听器返回单击的游戏片段

使用MouseEvent中的getX()和getY()方法

然后遍历“片段”数组列表,并在每个
片段中包含的
形状
上调用
包含(…
方法,查看鼠标点是否包含在片段中

因此,您还需要在“Piece”类中添加一个
getShape(…)
方法,以便可以访问每个
Piece
Shape

编辑:

因此,您的基本逻辑可能是:

//Shape polyShape = new Polygon(SHAPE_X, SHAPE_Y, SHAPE_X.length);
//Piece topLeft = new Piece(Color.YELLOW, polyShape,   0, 100, 100);
Polygon topLeftPolygon = new Polygon(SHAPE_X, SHAPE_Y, SHAPE_X.length);
topLeftPolygon.translate(100, 100);
//topLeftPolygon = ShapeUtils.rotate(...); // do rotation when required
Piece topLeft = new Piece(Color.YELLOW, topLeftPolygon);
那么draw(..)方法中的绘画代码就是:

gc.setColor(color);
gc.fill(shape);
不需要变换或平移

编辑2:

因此,请使用以下形状:

//topLeftPolygon = ShapeUtils.rotate(...); // do rotation when required
//Piece topLeft = new Piece(Color.YELLOW, topLeftPolygon);
Shape topLeftShape = ShapeUtils.rotate(...); // do rotation when required
Piece topLeft = new Piece(Color.YELLOW, topLeftShape);
这目前与你的Piece类相匹配,你的Piece类无论如何都需要一个Shape对象。请考虑所建议的概念,不要假设发布的代码是完美的,因为它显然还没有经过测试

因此,我需要找到一种方法来添加一个鼠标侦听器,该侦听器返回单击的游戏片段

使用MouseEvent中的getX()和getY()方法

然后遍历“片段”数组列表,并在每个
片段中包含的
形状
上调用
包含(…
方法,查看鼠标点是否包含在片段中

因此,您还需要在“Piece”类中添加一个
getShape(…)
方法,以便可以访问每个
Piece
Shape

编辑:

因此,您的基本逻辑可能是:

//Shape polyShape = new Polygon(SHAPE_X, SHAPE_Y, SHAPE_X.length);
//Piece topLeft = new Piece(Color.YELLOW, polyShape,   0, 100, 100);
Polygon topLeftPolygon = new Polygon(SHAPE_X, SHAPE_Y, SHAPE_X.length);
topLeftPolygon.translate(100, 100);
//topLeftPolygon = ShapeUtils.rotate(...); // do rotation when required
Piece topLeft = new Piece(Color.YELLOW, topLeftPolygon);
那么draw(..)方法中的绘画代码就是:

gc.setColor(color);
gc.fill(shape);
不需要变换或平移

编辑2:

因此,请使用以下形状:

//topLeftPolygon = ShapeUtils.rotate(...); // do rotation when required
//Piece topLeft = new Piece(Color.YELLOW, topLeftPolygon);
Shape topLeftShape = ShapeUtils.rotate(...); // do rotation when required
Piece topLeft = new Piece(Color.YELLOW, topLeftShape);
这当前与您的Piece类相匹配,该类无论如何都需要一个Shape对象。请考虑所建议的概念,不要假设发布的代码是完美的,因为它显然没有经过测试。

我看到您使用了我的,
    Piece hitTest(MouseEvent e) {
        final Point pnt = e.getPoint();
        return pieces.stream()
                     .filter(piece -> piece.hitTest(pnt))
                     .reduce((first, second) -> second)
                     .orElse(null);
    }