Java Canvas调用repaint无响应 围棋落子GUI界面无法更新
问题根因
你遇到的repaint不生效问题核心是实例对象不匹配,同时存在多个细节语法、逻辑错误:
- 核心错误:创建了两个独立的
GoGui实例,监听逻辑和渲染实例完全分离
main方法中你先实例化了myGui对象,又单独实例化了canvas对象添加到JFrame显示,但是你将myGui作为鼠标监听器绑定给了canvas。鼠标点击触发的是myGui的事件处理逻辑,修改的是myGui的myX、myY属性,调用的也是myGui的repaint()方法,而屏幕上显示的是完全独立的canvas实例,自然不会有任何渲染更新。 - 渲染参数错误:
Graphics.fillOval的四个入参分别是「左上角x坐标、左上角y坐标、宽度、高度」,你当前写的g.fillOval(myX-20, myY-20, myX+20, myY+20)会导致棋子大小随坐标动态变化,逻辑完全错误。 - 坐标获取逻辑错误:你用
MouseInfo.getPointerInfo().getLocation()拿到的是全局屏幕坐标,还需要扣除窗口标题栏、边框的偏移量,直接使用鼠标事件对象的e.getX()、e.getY()即可拿到相对于Canvas的本地坐标,不需要手动修正偏移。 - 语法缺失错误:你只实现了
MouseListener接口的mouseClicked方法,其余mousePressed、mouseReleased、mouseEntered、mouseExited四个方法需要补充空实现,否则编译无法通过;myCoords变量未声明类型,开头的import拼写错误为mport。
修复方案
- 仅保留一个
GoGui实例,自己作为鼠标监听器绑定给自己 - 修正棋子绘制参数和坐标计算逻辑
- 补全缺失的接口实现
核心修复代码
import java.awt.Canvas; import java.awt.Color; import java.awt.Graphics; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JFrame; public class GoGui extends Canvas implements MouseListener{ public int myX=60; public int myY=60; // 这里自行补全newPiece类定义和pieces逻辑 public static void main(String[] args) { GoGui canvas = new GoGui(); JFrame frame = new JFrame("Go Database"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLocation(50, 50); canvas.setSize(800, 800); Color TAN = new Color(255,255,170); frame.add(canvas); canvas.setBackground(TAN); canvas.addMouseListener(canvas); frame.pack(); frame.setVisible(true); } @Override public void paint(Graphics g) { g.setColor(Color.BLACK); int varcoor=20; while(varcoor<781) { g.drawLine(20, varcoor, 780, varcoor); varcoor+=40; } varcoor=20; while(varcoor<781) { g.drawLine(varcoor, 20, varcoor, 780); varcoor+=40; } // 修正棋子绘制参数,宽高固定为40(半径20) g.fillOval(myX-20, myY-20, 40, 40); } @Override public void mouseClicked(MouseEvent e) { // 直接使用事件自带的相对坐标 placePiece(e.getX(), e.getY()); } public void placePiece(double littleX, double littleY) { // 棋盘从x=20、y=20开始,网格间距40,直接计算最近交叉点 int bigX=(int) Math.round((littleX-20)/40); bigX = Math.max(0, Math.min(bigX, 18)); int bigY=(int) Math.round((littleY-20)/40); bigY = Math.max(0, Math.min(bigY, 18)); myX=(bigX*40)+20; myY=(bigY*40)+20; // 调用当前显示实例的repaint,触发重绘 repaint(); } // 补全MouseListener接口的其余方法 @Override public void mousePressed(MouseEvent e) {} @Override public void mouseReleased(MouseEvent e) {} @Override public void mouseEntered(MouseEvent e) {} @Override public void mouseExited(MouseEvent e) {} }
内容的提问来源于stack exchange,提问作者Crheadrick
相关产品推荐
相关产品推荐

