简体   繁体   中英

repaint() not working when called from mouse listener method

I am making a Solitaire program as a side project and I am having problems with the paint window I have made.

In the program, I am having a line start at one point that ends at the position of my mouse click. When I click on the window, it successfully reads my clicks and changes the xcor and ycor variables to my mouse click position, but fails to repaint a line using the new coordinates.

public class Game_Play extends JFrame {

public int xcor = 0;
public int ycor = 0;
public void setup() { //sets up JFrame
    JFrame frame = new JFrame();
    frame.setSize(500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocation(0, 0);
    frame.setTitle("Circles");
    frame.add(new MouseHandler());
    frame.addMouseListener(new MouseHandler());
    frame.addMouseMotionListener(new MouseHandler());
    frame.setVisible(true);
}

          //listener and painting subclass
class MouseHandler extends JPanel implements MouseListener, MouseMotionListener {
              //when mouse pressed, the Xcor and Ycor
              //will be changed to the current mouse 
              //x and y cords, then it will call 
              //repaint() to repaint the line using the
              //new Xcor and Ycor locations
    public void mousePressed(MouseEvent me) {
        System.out.println("mouse pressed");
        xcor = me.getX();
        ycor = me.getY();
                  //prints out new cords
        System.out.println(xcor + " xcor");
        System.out.println(ycor + " ycor");
        repaint();
    }

    public void mouseReleased(MouseEvent me) { //tests to make sure listener is working
        System.out.println("mouse released");
    }

    public void mouseClicked(MouseEvent me) {}
    public void mouseEntered(MouseEvent me) {}
    public void mouseMoved(MouseEvent me) {}
    public void mouseExited(MouseEvent me) {}
    public void mouseDragged(MouseEvent me) {}

              //paints the line with the Xcor and Ycor values
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        System.out.println("repaint check"); //test to see if repaint has been called
        g.drawLine(100, 100, xcor, ycor);
    }
}
}

Note: repaint() is being called from the MouseListener method mousePressed , I also have tried calling it from different MouseListener and MouseMotionListener methods to no avail.

Note: The paintComponent method notifies me if it has been called successfully, and when I click, the paintComponent method does not execute.

Note: I did notice that if I click on the screen to set the new cords then hit the maximize button on the window, it will successfully call the repaint method with a redrawn line using the new cords.

Note: the setup() method is being called from another class in another file, the code is as follows:

public static void main(String[] args) throws IOException {
  deck_Create();
  deck_Shuffle();
  game_setup();
  BufferedImage_array_Setup();
  //being called here
  Game_Play a = new Game_Play();
  a.setup();
  //
}

Last Note: I have searched high and low for the fix to this problem, only coming up with similar problems that didn't help me. Any Feedback given is greatly appreciated.

If there are any questions, let me know and I will address them for you in a few.

Thanks!

Some comment on your code:

public void setup() {
    JFrame frame = new JFrame();
    frame.setSize(500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocation(0, 0);
    frame.setTitle("Circles");
    frame.add(new MouseHandler());// your panel
    frame.addMouseListener(new MouseHandler()); // your listener, also a panel, but not the one you added to your frame
    frame.addMouseMotionListener(new MouseHandler()); // yet another listener, also not the panel you added to your frame
    frame.setVisible(true);
}

You probably meant to write:

public void setup() {
    JFrame frame = new JFrame();
    frame.setSize(500, 500);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocation(0, 0);
    frame.setTitle("Circles");
    JPanel p = new MouseHandler();
    frame.add(p);
    frame.addMouseListener(p);
    frame.addMouseMotionListener(p);
    frame.setVisible(true);
}

Note that having your UI components implement listener interfaces is not a good idea. What if you want to have two mouse listeners for different components in the panel? You can't have both listeners on the panel.

A better way is to have the listener interfaces implemented by anonymous classes, following the seperation of concerns guideline.

Another thing is to add the listeners to the components that should handle them. You should be registering these listeners on the panel, not the frame containing the panel.

And finally, you should be setting the panel as the content pane using setContentPane . Usually it's best to have the panel dictate what its size should be by overriding setPreferredSize . In that case you don't need to set the size of the containing frame, rather you call pack to size the frame to the preferred size of its subcomponents.

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