You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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。
修复方案
  1. 仅保留一个GoGui实例,自己作为鼠标监听器绑定给自己
  2. 修正棋子绘制参数和坐标计算逻辑
  3. 补全缺失的接口实现

核心修复代码

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 20:36:00