简体   繁体   中英

Paint method not painting Java

My paint method doesnt seem to paint my 20x20 cells. I have a boolean array for the cells to control their state and that if true, call the cells paint method, a cell is painted however I have two problems;

  1. Only one is painted at a time which is odd because i should have a 40x40 array of booleans meaning i have 40x40 cells

  2. They dont actually paint exactly where I click. I do not know how this is the case as when I get the co-ordinates of my click I immediately place those co-ordinates as my x, and y values in my paint method.

Main


import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferStrategy;

public class mainApplication extends JFrame implements Runnable, MouseListener {


    private static final Dimension windowsize = new Dimension(80, 600);
    private BufferStrategy strategy;
    private Graphics offscreenGraphics;
    private static boolean isGraphicsInitialised = false;
    private static int rows = 40;
    private static int columns = 40;
    private static int height = windowsize.height;
    private static int width = windowsize.width;
    private static Cells cells = new Cells();
    private int xArrayElement,yArrayElement, xPosition, yPosition;
    private static boolean gameState[][] = new boolean[rows][columns];


    public mainApplication() {


        System.out.println(System.getProperty("user.dir"));

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();

        int x = screensize.width / 2 - windowsize.width / 2;
        int y = screensize.height / 2 - windowsize.height / 2;

        setBounds(x, y, screensize.width, screensize.height);

        setVisible(true);

        createBufferStrategy(2);

        strategy = getBufferStrategy();

        offscreenGraphics = strategy.getDrawGraphics();

        isGraphicsInitialised = true;

       // MouseEvent mouseEvent = new MouseEvent();
        addMouseListener(this);
       // addMouseMotionListener(MouseEvent);

        Thread t = new Thread(this);

        t.start();

    }


    public void mousePressed(MouseEvent e) { }

    public void mouseReleased(MouseEvent e) { }

    public void mouseEntered(MouseEvent e) { }

    public void mouseExited(MouseEvent e) { }

    public void mouseClicked(MouseEvent e) {

        if(e.getClickCount() == 1){

               xPosition = e.getX();
               yPosition = e.getY();

           cells.setPosition(xPosition,yPosition);

            xArrayElement = (xPosition/20);
            yArrayElement = (yPosition/20);

            if(gameState[xArrayElement][yArrayElement]){
                gameState[xArrayElement][yArrayElement] = false;
            }
            else if (!gameState[xArrayElement][yArrayElement]) {
                gameState[xArrayElement][yArrayElement] = true;
            }
            else(gameState[xArrayElement][yArrayElement]) = true;
        }
    }

    @Override
    public void run() {
            while (true) {

                try { //threads entry point
                    Thread.sleep(20); //forces us to  catch exception
                }

                catch (InterruptedException e) {
                }
              this.repaint();
            }
        }


    public void paint(Graphics g) {

        if (isGraphicsInitialised) {
            g = strategy.getDrawGraphics();

            g.setColor(Color.BLACK);

            g.fillRect(0, 0, 800, 800);


                    if (gameState[xArrayElement][yArrayElement]) {
                        g.setColor(Color.WHITE);
                        cells.paint(g);
                        System.out.println(xPosition);
                    }

                    else if (!gameState[xArrayElement][yArrayElement]) {

                        g.setColor(Color.BLACK);
                        g.fillRect(xPosition, yPosition, 20, 20);
                    }

                strategy.show();
            }
        }

    public static void main(String[]args){

        mainApplication test = new mainApplication();

    }
}

Cell Class


import java.awt.*;

public class Cells {

    int x;
    int y;


    public Cells(){

    }

    public void setPosition(int xi, int xj){

        x = xi;
        y = xi;
    }

    public boolean cellState(boolean visible){

        return visible;
    }

    public void paint(Graphics g){

        g.drawRect(x, y, 20,20);
    }
}

You are doing a number of things wrong. My first suggestion would be to forget about offscreen graphics and ensure you are doing what you want. You can always create an image latter. Here are some basic guidelines:

  • Don't extend JFrame . Use an instance.
  • Extend JPanel or create a class that extends JPanel and add to frame instance
  • Then override paintComponent(g) and use that graphics context to draw.

Here is an earlier answer that may help Can't add Graphics into JPanel in Java

More information may be found in the Java Tutorials on painting.

Updated . It took me a few minutes to find this.

 public void setPosition(int xi, int xj){
        x = xi;
        y = xi; // <--- should be xj
 }

Regarding (1) above. You must repaint every cell each time you enter paintComponent . This means you will need to iterate across the list and paint them in the correct spot. Right now you are only painting one upon each entry.

A couple more suggestions. Instead of messing with the thread and calling repaint every 20ms in a loop, why not just invoke repaint in the mouseClicked() method.

If you do eventually need to paint every 20ms. I suggest using a swing Timer as follows: (check JavaDoc to ensure I got the syntax correct!!)

Timer timer  = new Timer(0, (ev)-> frame.repaint());
timer.setDelay(20);
timer.start();

And you can create your own mouseListener class and extending MouseAdapter . The purpose of these adapter classes is to keep the clutter down so you don't have to have empty methods to satisfy the interface requirements. Put the class inside your main class so it has access to the appropriate data structures. Then just add an instance of it to the mouse listener of the target Component.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM