Lewis Sherlock
Lewis Sherlock

Reputation: 7

Variable not passing over to method paint

I have been searching google for the past day and a half trying to figure this out. As you can see I am trying to make the mouseClicked update the variables clickcolumnindex and clickrowindex in order to make the replaint() method in the mouseClicked method update and thus show the counter created by paint display within another column/row.

I feel this may be a really simple fix after my trying loads of things, I have kinda lost my path of thought.

Help would be greatly appreciated.

import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;

            class GridPanel extends JPanel implements MouseListener
            {
                int numCols;
                int numRows;
                int w;
                int h;
                int x;
                int y;
                int clickcolumnindex;
                int clickrowindex;


                public void mouseReleased(MouseEvent event)
                {
                    System.out.println("Mouse released.");
                }
                public void mousePressed(MouseEvent event)
                {
                    System.out.println("Mouse Pressed");
                }
                public void mouseClicked(MouseEvent event)
                {
                    int clickcolumnindex = 7 * x / getWidth();
                    int clickrowindex = 5 * y / getHeight();
                    int x = event.getX();
                    int y = event.getY();
                    System.out.println("x position of click is: " +x);
                    System.out.println("y position of click is: " +y);
                    System.out.println("Click is in column " +clickcolumnindex);
                    System.out.println("Click is in row " +clickrowindex);
                    repaint();

                }


   public void mouseReleased(MouseEvent event) {
      System.out.println("Mouse released.");
   }

   public void mousePressed(MouseEvent event) {
      System.out.println("Mouse Pressed");
   }

   public void mouseClicked(MouseEvent event) {
      int x = event.getX();
      int y = event.getY();
      System.out.println("x position of click is: " + x);
      System.out.println("y position of click is: " + y);
      System.out.println("Click is in column " + clickcolumnindex);
      System.out.println("Click is in row " + clickrowindex);
      repaint();
   }

   public void mouseEntered(MouseEvent event) {
      System.out.println("Mouse entered.");
   }

   public void mouseExited(MouseEvent event) {
      System.out.println("Mouse exited.");
   }

   public GridPanel(int nc, int nr) {
      numCols = nc;
      numRows = nr;
      addMouseListener(this);
   }

   Rectangle getRect(int thisCol, int thisRow) {
      // if input is out of range, return "null"
      if (thisCol < 0 || thisRow < 0)
         return null;
      if (thisCol >= numCols || thisRow >= numRows)
         return null;
      // otherwise, make and return the Rectangle
      int w = getWidth() / numCols;
      int h = getHeight() / numRows;
      int x = thisCol * w;
      int y = thisRow * h;
      Rectangle myRect = new Rectangle(x, y, w, h);
      return myRect;
   }

   public void paint(Graphics g) {
      g.setColor(Color.gray);
      g.fillRect(0, 0, getWidth(), getHeight());
      g.setColor(Color.black);
      Graphics2D g2 = (Graphics2D) g;
      // we'll use Graphics2D for it's "draw" method -
      // neater than the Graphics "drawRect" suppled
      // (which you could also use)
      for (int i = 0; i < numCols; i++) {
         for (int j = 0; j < numRows; j++) {
            Rectangle r = getRect(i, j);
            g2.draw(r);
         }
      }
      g2.setColor(Color.blue);
      Rectangle r1 = getRect(clickcolumnindex, clickrowindex);
      g2.fillOval(r1.x, r1.y, r1.width, r1.height);
      System.out.println("variable updates " + clickcolumnindex + clickrowindex);
   }

   // copied from the W2MouseEvents for convenience
   // (so we can run the program from GridPanel class too!)
   public static void main(String[] args) {
      W2MouseEvents w = new W2MouseEvents();
      w.setVisible(true);
   }
}

W2MouseEvents.java:

import javax.swing.JFrame;

public class W2MouseEvents extends JFrame {
   GridPanel myGridPanel;

   public static void main(String[] args) {
      W2MouseEvents w = new W2MouseEvents();
      w.setVisible(true);
   }

   public W2MouseEvents() {
      setTitle("Workshop 2 (Mouse Events): starting code");
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setSize(500, 400);
      setLocation(300, 300);
      myGridPanel = new GridPanel(7, 5);
      add(myGridPanel);
   }

}

Upvotes: 0

Views: 1334

Answers (3)

Tedil
Tedil

Reputation: 1933

There are at least two issues: Variables do not magically auto-update themselves. If x is changed, no variable which has got x on its righthand side (assuming they are in the same scope) get updated. To clarify:

int x = 4;
int var = x + 1; // var == 5
x = 5 // var still is 5, not 6

Assuming you want to change x and y "globally" (as in "attributes of an instance of your class"), the second issue you'll have to address is

public void mouseClicked(MouseEvent event)
{
    int x = event.getX();
    int y = event.getY();
    // ...
}

What happens here is that you declare two new local variables x and y but whatever value you assign to them, your "global" variables x and y will not change unless you leave out the declarative int. This is not an issue if you recalculate the value of clickColumnIndex and clickRowIndex inside one of the mouseClicked/mousePressed/... methods.

Edit I see you've moved the calculation of clickColumnIndex and its brother to the mouseClicked method. But as stated above, you are creating two new variables which hide the "global" ones. Simply remove the int.

Upvotes: 3

Reimeus
Reimeus

Reputation: 159754

The statements:

   int clickcolumnindex = 7 * x / getWidth();
   int clickrowindex = 5 * y / getHeight();

are not allowed outside constructors, methods or static initializer blocks.

As indicated by the HoverMeister, these are only assiged once. Why not have a separate method for updating these variables and a subsequent repaint()?

Upvotes: 1

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

You set clickcolumnindex when you declare it, before a mouse event ever occurs. You need instead to set it in the mouse listener.

In other words, this is meaningless:

        class GridPanel extends JPanel implements MouseListener
        {
            int numCols;
            int numRows;
            int w;
            int h;
            int x;
            int y;
            int clickcolumnindex = 7 * x / getWidth();
            int clickrowindex = 5 * y / getHeight();

because at this point x is 0 and so is getWidth() (surprised you don't get a divide by zero error here).

You want to set clickXXXindex in the MouseListener's mousePressed(...) method instead. I prefer using mousePressed(...) rather than mouseClicked(...) as the former isn't as picky about if you move the mouse after pressing it.

Also, you'll want to do your drawing in the JPanel's paintComponent(...) method, not its paint(...) method.

Upvotes: 1

Related Questions