0

I am working on a program that allows the user to place pieces on a Go board, and updates to place the pieces on the nearest intersection to the user's click in a GUI. I've figured I use the repaint() method for this, (the math part of it should already be working) but I've struggled to manage to get anything actually updated on the canvas at all past its initial creation. Most forms of repaint I've seen online use either JPanel or Applets instead of Canvas, or paintComponent instead of paint, but using both regular paint and canvas is the only way I've managed to get the board to even initially be created. My code is as follows, and, for clarity, my exact problem is that the repaint call seemingly just does absolutely nothing.

mport java.io.IOException;

import java.util.EventListener; 
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.util.ArrayList;
import java.util.Random;
import java.awt.Graphics;
import java.applet.Applet;

import javax.swing.JButton;
import javax.swing.JFrame;
import java.awt.BorderLayout;
import java.awt.Button;
import java.awt.GridLayout;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.*;

public class GoGui extends Canvas implements MouseListener{
public int myX=21;
public int myY=21;
public ArrayList <newPiece> pieces=new ArrayList<newPiece>();
    public static void main(String[] args) {
        GoGui myGui=new GoGui();
        JFrame frame = new JFrame("Go Database");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocation(50, 50);
        frame.setSize(800, 800);
        myGui.setSize(800, 800);
        Canvas canvas = new GoGui();
        canvas.setSize(800, 800); 
        Color TAN = new Color(255,255,170);
        frame.add(canvas);
        canvas.setBackground(TAN);
        canvas.addMouseListener(myGui);
        frame.pack();
        frame.setVisible(true);
    }
    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;
        }
        g.fillOval(myX-20, myY-20, myX+20, myY+20);
    }
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub
        myCoords=MouseInfo.getPointerInfo().getLocation();
        myX=myCoords.x;
        myY=myCoords.y;
        placePiece((double) myX,(double) myY);
        
    }
    public void placePiece(double littleX, double littleY) {
        littleX=(littleX-70)/40;
        int bigX=(int) Math.round(littleX);
        if(bigX<1) {
            bigX=1;
        }
        if(bigX>18) {
            bigX=18;
        }
        littleY=(littleY-70)/40;
        int bigY=(int) Math.round(littleY);
        if(bigY<1) {
            bigY=1;
        }
        if(bigY>18) {
            bigY=18;
        }
        myX=(bigX*40)+20;
        myY=(bigY*40)+20;
        repaint();
    }
    }

If anyone has experience with this specific Java concept and could point me in the right direction, it would be greatly appreciated.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • 1
    *Most forms of repaint I've seen online use either JPanel* - which is correct. When using Swing you should use a `JPanel` and override `paintComponent()`. Canvas is an AWT component and should not be used with Swing. Read the tutorial on [Custom Painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/index.html) for a complete working example. Start with the working example and make changes one at a time. Then if it stops working you know what you just changed. – camickr Oct 18 '21 at 14:05
  • *the repaint call seemingly just does absolutely nothing.* - All the repaint() method does is paint the panel in its current state. If you haven't changed the state of the class then nothing will change. Did you add debug code in your method to make sure the method is invoked? Do you display the new x/y values to make sure you math is correct? – camickr Oct 18 '21 at 14:07
  • You are getting the position from `MouseInfo.getPointerInfo()` instead of from the `MouseEvent` that is passed to your event handler with `e.getPoint()` or `e.getX()` and `e.getY()`. This gives you the position on the screen, not the position within your component. – David Conrad Oct 18 '21 at 14:16
  • In addition to previous comments: there is no need for two instances of `GoGui` : `GoGui myGui=new GoGui();` and `Canvas canvas = new GoGui();`. Use only the later and `canvas.addMouseListener(canvas);` or better `addMouseListener(this);` in `GoGui` constructor. – c0der Oct 18 '21 at 14:17
  • 1
    @c0der Good catch! The mouse listener is being added to the wrong instance! – David Conrad Oct 18 '21 at 14:27
  • 1
    Here's a recent [Stack Overflow answer](https://stackoverflow.com/questions/68893598/how-to-make-a-grid-of-buttons/69034066#69034066) when I create a 9 x 9 Go board using a drawing JPanel. – Gilbert Le Blanc Oct 18 '21 at 14:45
  • I managed to get everything working based on the advice here, using the JPanel means as well as other advice. Thank you for the help, everyone! – Crheadrick Oct 19 '21 at 19:59

0 Answers0